Extract 1024bit modulus from RSA key - encoding

I know there's a billion answers on how to extract the modulus from an RSA key (I have a .cer file) and I want the 1024 bit (it's 1024 bit in my case) value from it. What I don't get is the following:
When I extract it, it's always not 1024 bits, but more. Has that something to do with padding or...? Looks like 136 bytes at the moment, so 64 bit too much. Not sure whether this is a constant or depends on the certificate
edit:
I retried with openssl x509 -modulus -inform PER -in file.cer and it resulted in 128 bytes. Guess that's it.
edit2:
So, this still is my problem. I did openssl x509 -inform DER -in file.cer -text and got a modulus of 129 bytes. Is my assumption correct that I can skip the first one because it is 0x00 which might just be used to make the whole thing positive again (first byte otherwise would be a 0xaa which might be negative)?

Related

What input is used when openssl creates digest for a file?

When I type
openssl sha256 filename.pdf
What value is used to create a digest? Is it a meta data of that file or every byte data of that pdf? I tried openssl sha256 on a large files(~2GB) and it did not take a long time, so my guess is that openssl does not use every byte in a file. So what value(byte) is used?

netbsd - weird hash format for sha1

On my NetBSD system, there is a password hash in master.passwd that looks like this:
$sha1$[5 numbers]$[8 letters]$[17 alpha numeric].[10 alpha numeric]
For privacy concerns I left out the actual values. Would someone be willing to explain the different parts of this? I was under the impression that SHA1 resulted in 20 bytes, so I was very confused about what part was the actual hash, and what part was the salt, and what part everything else was.
The relevant parts can be found in NetBSD src/lib/libcrypt.
For the format: crypt-sha1.c
The format of the encrypted password is:
$<tag>$<iterations>$<salt>$<digest>
where:
<tag> is "sha1"
<iterations> is an unsigned int identifying how many rounds
have been applied to <digest>. The number
should vary slightly for each password to make
it harder to generate a dictionary of
pre-computed hashes. See crypt_sha1_iterations.
<salt> up to 64 bytes of random data, 8 bytes is
currently considered more than enough.
<digest> the hashed password.
The digest is 160 bits = 20 bytes, but it is encoded using base64 (4 bytes for 3 source bytes) to 28 bytes (with one zero padding byte). See util.c for that.

What is the difference between the different padding types on iOS?

On iOS, the Certificate, Key, and Trust Services API contains the following padding types:
kSecPaddingNone
kSecPaddingPKCS1
kSecPaddingPKCS1MD2
kSecPaddingPKCS1MD5
kSecPaddingPKCS1SHA1
A user on the Apple CDSA mailing list says that "kSecPaddingPKCS1 [...] is the same as PKCS #1 1.5". The Certificate, Key, and Trust Services Reference annotates the latter three padding types (kSecPaddingPKCS1MD2, kSecPaddingPKCS1MD5, and kSecPaddingPKCS1SAH) with "Standard ASN.1 padding will be done, as well as PKCS1 padding of the underlying RSA operation".
What is the difference to kSecPaddingPKCS1?
Is kSecPaddingPKCS1 just the raw padding of the underlying RSA operation according to RFC 3447?
When signing a SHA-256, SHA-384, or SHA-512 digest with SecKeyRawSign(), does a developer need to use kSecPaddingPKCS1 and perform the ASN.1 padding herself? Is the ASN.1 padding necessary or can it be omitted?
Any hint that points me in the right direction is highly appreciated.
PKCS#1 contains two "paddings" for signatures with RSA, the "new" one (called PSS, added in version 2.1) and the "old" one (renamed "v1.5" since it was already in version 1.5 of PKCS#1). We are talking about the v1.5 padding.
When some data is signed, it is first hashed with a suitable hash function (e.g. SHA-1), then the hash value (20 bytes if using SHA-1) is wrapped into two successive layers:
The hash value is encoded into an ASN.1-based structure which also specifies which hash function was used. In practice, if the hash value is H, then the first wrapping results in the sequence of bytes A || H where "||" is concatenation, and "A" is a header which is specific to the hash function (typically 15 to 20 bytes).
The "A || H" is expanded with some extra bytes:
0x00 0x01 0xFF 0xFF ... 0xFF 0x00 || A || H
The number of bytes of value 0xFF is adjusted to that the total size equals the size of the RSA modulus (i.e. 128 bytes for a 1024-bit RSA key).
The second step is what PKCS#1 calls "type 1 padding".
kSecPaddingPKCS1 means that the function performs only the second step: it assumes that the input data is already the proper "A || H". Note that SSL/TLS (up to version 1.1) uses a signature variant which requires this mode (there's no "A", but there are two hash functions). With kSecPaddingPKCS1SHA1, the signature function expects the hash value as input, and adds the "A" header itself.
For a proper, standards-compliant signature which can be verified by third-party implementations, the "A" header must be added at some point. You can add it yourself and use kSecPaddingPKCS1, or use kSecpaddingPKCS1SHA1 and let the engine add it itself, which is probably less error-prone.
(As of 2011, use of SHA-1 is not recommended; you'd better switch to SHA-256 or SHA-512. Also, the API you are trying to use seem to be quite low-level, and the whole thing suspiciously looks as if you are tying to implement your own cryptographic protocol instead of using an existing library or framework.)

AES algorithm input and output restrictions

I want to use AES encryption in my application. I have come across some open source implementations of aes algorithm. By looking at them, I am confused about the following parameters:
AES key length. It is mentioned that key length should be 128, 192 or 256 bytes. What if my key is simply five digits i.e. 23467
AES plain-text length : is there any restriction on the aes plain-text length ?
AES output: What would be the minimum size of aes output string if my key length is say 5 digits and plain-text is say 10 characters.
Can anyone help me?
AES key length. It is mentioned that key length should be 128, 192 or 256 bits. What if my key is simply five digits i.e. 23467
It seems you're thinking of the key as a password of sorts. It isn't. A cryptographic key isn't meant to be memorized. It is a long string of randomly generated bytes that should be stored somewhere safe.
You can derivate a cryptographic key from a password, though, for instance using a hash function. In that case you input 234567 and use the resulting digest as the key. This has some security implications, however, as it makes your key vulnerable to dictionary and rainbow table attacks. Look up "password based encryption" for details on how to approach this securely; in particular, have a look at PBKDF2, described in RFC2898.
AES plain-text length : is there any restriction on the aes plain-text length ?
AES is the block cipher, the underlying building block of an encryption system. By itself it can only encrypt a single block of data (16 bytes), so cryptographers have created several "modes of operation" that enable us to encrypt a plaintext of arbitrary length. CTR is a fine example of a mode of operation that does not require any padding and can be parallelized.
AES output: What would be the minimum size of aes output string if my key length is say 5 digits and plain-text is say 10 characters.
That's entirely dependent on the mode of operation. In your case it will probably be either 10 (when no padding is required, for example with CTR) or 16 (for block-based modes such as CBC).
I think you mean 128 and 256. (Not 198.)
That's not a key. That's a password. You use an algorithm like PBKDF1 (google it) to derive a key from a password.
No. AES is a block cipher. It works on input blocks that are the same size as the key. You can use as many blocks as you like, chopping up your input into (say) 128-bit blocks. Make sure you use CBC or a similar mode for AES.
Your key is 128 or 256 bits. Your input would be 80 bits (10*8), padded to 128 or 256. Your output length is the same as the key size.
Try to find a crypto library that does most of the work for you. You don't want to mess around with just a basic AES function. You also need to handle IVs, AES modes, possibly a MAC, etc. I can't recommend anything because you don't say what language you're trying to use.

Which symmetrical encryption algorithm to use to encrypt e-mail address(short message)?

Which symmetrical encryption algorithm to use to encrypt e-mail address(short message)? I would like to have ciphertext to be comparable in length to paintext.
According to Little known features: Symmetric encryption with PGP/GPG:
A little known feature of both PGP and
GPG is that they can also do symmetric
encryption. Just a passphrase is
needed- no public or private keys are
involved. It’s a quick and dirty way
to get strong encryption that even a
novice can use.
To encrypt a file with symmetric
encryption, the syntax is:
pgp --symmetric filename
gpg --symmetric filename
The result is a binary file with the
same name as the original and ".pgp"
or ".gpg" appended.
If the encrypted file must be pasted
into the body of an e-mail message
(instead of added as an attachment),
you’ll want to use the plain ASCII
form of output:
pgp --symmetric --armor filename
gpg --symmetric --armor filename
The result is a plain text file ending
in ".asc"
Decryption is performed using the
usual "-d" switch:
pgp -d filename
gpg -d filename
But I'm not sure this is what you're looking for. Maybe you can clarify your question.
If you really want to have the cipher text comparable in length to the email address, you can use a block cipher in a mode like CFB or OFB that allows encryption of one byte at a time.
However, I don't recommend it, because that gives an attacker a little information about what the message is (how long is the message?). Using an algorithm like 3DES or AES with 16-byte blocks in CBC mode with PKCS #5 padding, most email addresses will be encrypted in two blocks.
I see there is a bit of confusion about lengths of plaintext/ciphertext. Actually, those lengths are quite similar if you use a symmetric encryption algorithm.
Consider a block cipher (e.g. AES). It encrypts 128-bit blocks into 128-bit blocks. So if your plaintext is exactly 128 bits (or its multiple), AES in any mode of operation will produce the ciphertext with the same length. If your plaintext length is not a multiple of 128 bits, then it will get padded to the full block and the ciphertext will be slightly longer (by at most 127 bits). You still can avoid that by using some tricks like ciphertext stealing.
If you use a stream cipher, the encryption process is just XOR-ing bits (or bytes) of the plaintext with bits (or bytes) of the keystream and then the length of the ciphertext is by definition equal to the length of the plaintext.
To answer directly your question, if you don't need any specific format of the encrypted email, just use AES.
If you want the encrypted email to be also in the format of an email, you may want to check how Format-Preserving Encryption works.
#Bobby: ROT13 is NOT an encryption algorithm.
Symmetric block ciphers produce the same length as the input, in multiples of block size (usually 8 bytes or 16 bytes for AES). Because the output is always multiple of block sizes (in fact the output is always the same size as the input and the input must be multiple of block sizes) then you cannot know the original size of the plain text. Common encryption schemes solve this by adding a padding scheme, like PKCS, ISO 10126 or ANSI X923. These schemes place information about the original clear text length in the last block.
If the clear text size is multiple of 8 (16 for AES) then one more block is added to the encrypted text. If the original size is not multiple of block size, then the encrypted size will be rounded up to the next multiple block size.
To this you should add a salt value for each record. A salt (or initialization vector, to be correct) has the same size as a block. Usually is stored in front of the encrypted block.
And finaly you should sign the encrypted value for validation, so you should add a SHA digest, another 20 bytes, otherwise you cannot know for sure if the decrypted value is correct.
So the overall size is (considering AES): 16 bytes (salt) + (clear text size + 20(hash) ) + (16 - (clear text size + 20)%16).
So for john.doe#anydomain.com (lenght 22) the encrypted size will be 16+22+20+(16-10)=64. To decrypt you take the first 16 bytes as salt, decrypt the remaininf 48, the output is lenght 42, you digest SHA the 42-20 = 22 bytes and compare the digets with the last 20 bytes of the decrypted text for validation.
I know is maybe more than you bargained for, but every step in this scheme has a justification.
I would suggest looking into PGP.
To have cypher results comparable with plain text is not a good idea, having differents lenghts is a part of what encryption is about.
I will suggest you one of the most secure encryption algorithms today: AES
But forget about having comparable sizes!
ROT13 or a substitution cypher might work (keys can be changed or exchanged). Encryption with keeping the original text length is...not really that good.
Bobby