I'am trying to encrypt a bigger file with the public_key module. Everything works fine as long as the content of the file is small. But when the size of the binary exceed's a certain size I get a **error:encrypt_failed. I guess this has to do with the padding parameter.I use this code to perform the encryption public_key:encrypt_private(Input, PrivKey); _______________________________________________ erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
Hi Marcus,
The encrypt_private is doing an RSA encryption using PKCS1 padding by default. RSA can't encrypt large payloads (i.e. 256 bytes - 11 for padding for 2048 bit RSA keys) so this is the likely reason you can only encrypt small portions of the file. Normally you use public key crypto to encrypt a symmetrical key and then encrypt the large payload with the symmetric key using AES or something. In addition you don't want to encrypt using the private key but rather the public key, otherwise anyone with access to your public key can decrypt the cipher. Private key encryption is usually only used for signatures. Crypto is hard to get right, especially if you are only working with RSA primitives (you need to think about padding, hashing, MDCs, signatures). You might want to have a look a NaCl (https://github.com/jloius/enacl for a binding to erlang) which is much friendlier to use. Cheers, Martin On Tuesday, 14 April 2015, Marcus Nilsson <[hidden email]> wrote:
_______________________________________________ erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
Thanks for the reply Martin and helping me with this.
The reason for doing this is that I want to share the files with a few people. After getting a better understanding of how this works I changed the my approach to this. Encryption 1. A shared secret is generated in the following form [Key, IV] 2. This secret is then used to encrypt the binary with aes_cfb128 a symmetric block encryption algo 3. The secret is then encrypted with the private key with RSA a asymmetric encryption algo 4. Both the encrypted shared secret and content is concatenated in the output file like this <<SharedSecretLength, EncryptedSecret, EncryptedContent>> Decryption 1. Extract the encrypted secret from the file 2. Decrypt the shared secret with the public key with RSA 3. Decrypt the encrypted content with the now decrypted secret with aes_cfb128 algo The following snippet seems to do the job Key = crypto:rand_bytes(16), IV = crypto:rand_bytes(16), EncryptedContent = crypto:block_encrypt(aes_cfb128, Key, IV, Input), EncryptedKey = public_key:encrypt_private(list_to_binary([Key, IV]), PrivKey), [integer_to_binary(byte_size(EncryptedKey)), EncryptedKey, EncryptedContent]. Thanks /Marcus 2015-04-14 0:54 GMT+02:00 Martin Karlsson <[hidden email]>: > Hi Marcus, > > The encrypt_private is doing an RSA encryption using PKCS1 padding by > default. > > RSA can't encrypt large payloads (i.e. 256 bytes - 11 for padding for 2048 > bit RSA keys) so this is the likely reason you can only encrypt small > portions of the file. > > Normally you use public key crypto to encrypt a symmetrical key and then > encrypt the large payload with the symmetric key using AES or something. > > In addition you don't want to encrypt using the private key but rather the > public key, otherwise anyone with access to your public key can decrypt the > cipher. Private key encryption is usually only used for signatures. > > Crypto is hard to get right, especially if you are only working with RSA > primitives (you need to think about padding, hashing, MDCs, signatures). You > might want to have a look a NaCl (https://github.com/jloius/enacl for a > binding to erlang) which is much friendlier to use. > > Cheers, > Martin > > > On Tuesday, 14 April 2015, Marcus Nilsson <[hidden email]> wrote: >> >> I'am trying to encrypt a bigger file with the public_key module. >> Everything works fine as long as the content of the file is small. >> >> But when the size of the binary exceed's a certain size I get a >> **error:encrypt_failed. I guess this has to do with the padding parameter. >> >> But I have not been able to find any documentation how to compute the >> padding to get this working any help would be very welcomed! >> >> I use this code to perform the encryption >> >> public_key:encrypt_private(Input, PrivKey); >> >> /Marcus erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
Hi Marcus,
It is getting better:) My only problem with this is that you are still using private_encrypt (end hence public decrypt). How are you going the distribute the RSA public key? Normally the public key is meant to be public but if something is encrypted using the RSA private key *any* party holding the RSA public key can decrypt the cipher. This means that you need to securely deliver the RSA public key. And if you had a way to securely distribute a key you wouldn't need RSA crypto in the first place:) (you would of course then securely distribute the shared secret) Public Key Crypto is mainly there to be able to share a secret key and this can be done in one of two ways: 1) Your friends send their public RSA key to you. You do encryption as above but replace step 3 with a public encrypt using your friends RSA key. Then they will decrypt the shared secret using their private key. In this case it doesn't matter who gets the public key because it is only the one holding the private key that can decrypt. 2) You send your friends your public RSA key. They generate a shared secret which they encrypt using your public key and then sends to you. You decrypt the shared secret with your private key and then use that shared secret to encrypt the file and send to you friend. Hopefully I've got this right. Cheers, Martin _______________________________________________ erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
hi Martin, just to add a little to step 1 ) there is also the option of encrypting one file but using multiple recipients for that single encryption step instead of looping and encrypting it differently for each recipients public key so marcus could obtain a list of all the recipients keys and encrypt the single file he wants to send around and get a single output encrypted file which is sent to all the recipients . each recipient can decrypt the output file using his own private key . this can prove convenient especially when u have multiple recipients for the same file . i use bash/gpg for this on a daily basis to send sensitive files to multiple recipients but the idea can still be used in your scenario above . On Tue, Apr 14, 2015 at 9:28 PM, Martin Karlsson <[hidden email]> wrote: Hi Marcus, _______________________________________________ erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
In reply to this post by Marcus Nilsson
On Tue, Apr 14, 2015 at 3:54 PM, Marcus Nilsson <[hidden email]> wrote:
> Thanks for the reply Martin and helping me with this. > > The reason for doing this is that I want to share the files with a few people. > After getting a better understanding of how this works I changed the > my approach to this. > > Encryption > 1. A shared secret is generated in the following form [Key, IV] > 2. This secret is then used to encrypt the binary with aes_cfb128 a > symmetric block encryption algo > 3. The secret is then encrypted with the private key with RSA a > asymmetric encryption algo > 4. Both the encrypted shared secret and content is concatenated in the > output file like this <<SharedSecretLength, EncryptedSecret, > EncryptedContent>> > > Decryption One alternative you might like to consider is making the envelope with term_to_binary To encode say Bin = term_to_binary({rsa_aes, EncryptedSecret, EncryptedContent}) and to decode {Tag, X, Y} = binary_to_term(Bin) The tag tells how the arguments were encrypted - this can be extended to make multiple nested containers (rather like the ASN.1 containers used in RSA etc. but far easier :-) /Joe > > 1. Extract the encrypted secret from the file > 2. Decrypt the shared secret with the public key with RSA > 3. Decrypt the encrypted content with the now decrypted secret with > aes_cfb128 algo > > The following snippet seems to do the job > > Key = crypto:rand_bytes(16), > IV = crypto:rand_bytes(16), > EncryptedContent = crypto:block_encrypt(aes_cfb128, Key, IV, Input), > EncryptedKey = public_key:encrypt_private(list_to_binary([Key, > IV]), PrivKey), > [integer_to_binary(byte_size(EncryptedKey)), EncryptedKey, > EncryptedContent]. > > Thanks > /Marcus > > 2015-04-14 0:54 GMT+02:00 Martin Karlsson <[hidden email]>: >> Hi Marcus, >> >> The encrypt_private is doing an RSA encryption using PKCS1 padding by >> default. >> >> RSA can't encrypt large payloads (i.e. 256 bytes - 11 for padding for 2048 >> bit RSA keys) so this is the likely reason you can only encrypt small >> portions of the file. >> >> Normally you use public key crypto to encrypt a symmetrical key and then >> encrypt the large payload with the symmetric key using AES or something. >> >> In addition you don't want to encrypt using the private key but rather the >> public key, otherwise anyone with access to your public key can decrypt the >> cipher. Private key encryption is usually only used for signatures. >> >> Crypto is hard to get right, especially if you are only working with RSA >> primitives (you need to think about padding, hashing, MDCs, signatures). You >> might want to have a look a NaCl (https://github.com/jloius/enacl for a >> binding to erlang) which is much friendlier to use. >> >> Cheers, >> Martin >> >> >> On Tuesday, 14 April 2015, Marcus Nilsson <[hidden email]> wrote: >>> >>> I'am trying to encrypt a bigger file with the public_key module. >>> Everything works fine as long as the content of the file is small. >>> >>> But when the size of the binary exceed's a certain size I get a >>> **error:encrypt_failed. I guess this has to do with the padding parameter. >>> >>> But I have not been able to find any documentation how to compute the >>> padding to get this working any help would be very welcomed! >>> >>> I use this code to perform the encryption >>> >>> public_key:encrypt_private(Input, PrivKey); >>> >>> /Marcus > _______________________________________________ > erlang-questions mailing list > [hidden email] > http://erlang.org/mailman/listinfo/erlang-questions erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
In reply to this post by Martin Karlsson-2
On Tue, Apr 14, 2015 at 11:28 PM, Martin Karlsson
<[hidden email]> wrote: > Hi Marcus, > > It is getting better:) > > My only problem with this is that you are still using private_encrypt > (end hence public decrypt). > > How are you going the distribute the RSA public key? Normally the > public key is meant to be public but if something is encrypted using > the RSA private key *any* party holding the RSA public key can decrypt > the cipher. > > This means that you need to securely deliver the RSA public key. And > if you had a way to securely distribute a key you wouldn't need RSA > crypto in the first place:) (you would of course then securely > distribute the shared secret) There is a slight variation on this: Distribute the SHA1 checksum of the RSA public key (this also needs a secure channel) - but the SHA1 checksum is far shorter so can be scribbled on the back of an envelope. If anybody claims to have the public key you can ask them for it and validate with the SHA1 checksum - this can take place over an insecure channel, since a man-in-the-middle will cause the SHA1 checksum to be invalid. This is one of the tricks used in the self certifying file system (see) http://web.archive.org/web/20080725193436/http://www.fs.net/sfswww/sfsfaq.html There's a very nice paper that has this idea http://www.scs.stanford.edu/~dm/home/papers/mazieres:escape.ps.gz Self certifying systems need no centralized key authority :-) /Joe > > Public Key Crypto is mainly there to be able to share a secret key and > this can be done in one of two ways: > > 1) Your friends send their public RSA key to you. You do encryption as > above but replace step 3 with a public encrypt using your friends RSA > key. Then they will decrypt the shared secret using their private key. > > In this case it doesn't matter who gets the public key because it is > only the one holding the private key that can decrypt. > > 2) You send your friends your public RSA key. They generate a shared > secret which they encrypt using your public key and then sends to you. > You decrypt the shared secret with your private key and then use that > shared secret to encrypt the file and send to you friend. > > Hopefully I've got this right. > > Cheers, > Martin > _______________________________________________ > erlang-questions mailing list > [hidden email] > http://erlang.org/mailman/listinfo/erlang-questions erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
Thanks Joe,
> This is one of the tricks used in the self certifying file system > (see) http://web.archive.org/web/20080725193436/http://www.fs.net/sfswww/sfsfaq.html > There's a very nice paper that has this idea > http://www.scs.stanford.edu/~dm/home/papers/mazieres:escape.ps.gz > > Self certifying systems need no centralized key authority :-) Very useful. Cheers, Martin _______________________________________________ erlang-questions mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-questions |
Free forum by Nabble | Edit this page |