Private key encryption

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Private key encryption

Marcus Nilsson
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
Reply | Threaded
Open this post in threaded view
|

Re: Private key encryption

Martin Karlsson-2
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
Reply | Threaded
Open this post in threaded view
|

Re: Private key encryption

Marcus Nilsson
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
Reply | Threaded
Open this post in threaded view
|

Re: Private key encryption

Martin Karlsson-2
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
Reply | Threaded
Open this post in threaded view
|

Re: Private key encryption

Nuku Ameyibor
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,

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


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Private key encryption

Joe Armstrong-2
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
Reply | Threaded
Open this post in threaded view
|

Re: Private key encryption

Joe Armstrong-2
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
Reply | Threaded
Open this post in threaded view
|

Re: Private key encryption

Martin Karlsson-2
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