Deimos
Deimos

Reputation: 117

256 byte long RSA encryption of AES key

I am trying to RSA encrypt the AES key of 32 chars length. Finally managed to do so with the help of the pre-generated public key and this RSA implementation for objective-C: https://github.com/ideawu/Objective-C-RSA/blob/master/RSA.m

NSData *enc = [RSA encryptData:data publicKey:pubkey];

Which then calls the library's methods. Basically, what it does is the following: it creates a SecKeyRef from public key, then it calculates the block_size, data_size etc. And finally it calls the

SecKeyEncrypt(keyRef, kSecPaddingPKCS1, srcbuf + idx, data_len, outbuf, &outlen);

I don't really understand what is going inside the encryption methods, but the outcome is the correctly created encrypted key.

Then I am able to decrypt it with a public key with the help of

SecKeyDecrypt(keyRef, kSecPaddingNone, srcbuf + idx, data_len, outbuf, &outlen);

The result is absolutely correct.

But the encoded key is 144 bytes long. It is not what I need. For some reason I need the key to be exactly 256 bytes.

My first thought was to fill the rest bytes with some constant variable (e.g. 0), but I thought it is not how it should be done.

The next thought was to use different padding. The name kSecPaddingPKCS1SHA256 sounded like the correct padding, but encoding the key with it instead of the kSecPaddingPKCS1 caused the app to fail with the error:

SecKeyEncrypt fail. Error Code: -50

I suppose it has something to do with the block_size, but I have little understanding of the insides of the encryption.

I need the encoded key to be exactly 256 bytes long, how can I do that?

Upvotes: 1

Views: 3187

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 94038

You need to encrypt your data with an RSA key of 2048 bits (i.e. 256 bytes). In that case the modulus will be 256 bytes and the resulting ciphertext - in this case the wrapped key - will be of that size as well.

What you do not need to do is to prefix the decrypted AES key to the ciphertext - that doesn't make sense. What you need to do is to prefix the encrypted or wrapped AES key using the public key of the receiver.

After decryption the resulting AES key should be 256 bits (i.e. 32 bytes) again.


As for the padding, the padding should always be identical during encryption and decryption. Currently only OAEP padding is considered secure. If you use PKCS#1 padding you must make sure that you're not vulnerable against padding oracle attacks.

For the same reason it is recommended to use AES-GCM instead of CBC, CBC is also vulnerable against padding oracle attacks.

1024 bit RSA is usually not considered secure anymore. Use a key of 2048 at the very minimum.

Upvotes: 1

Related Questions