0

Is it normal that the keypair of RSA (private and public) have the same ciphertext when I encrypt them with AES 256?

In fact I'm using PHP:

<?php


$key="abc";

$config = array(
    "digest_alg" => "sha512",
    "private_key_bits" => 4096,
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
);

// Create the private and public key
$res = openssl_pkey_new($config);

// Extract the private key from $res to $privKey
openssl_pkey_export($res, $privKey);

// Extract the public key from $res to $pubKey
$pubKey = openssl_pkey_get_details($res);
$pubKey= $pubKey["key"];


   aes256Key = hash("SHA256", $password, true);

// for good entropy (for MCRYPT_RAND)
srand((double) microtime() * 1000000);
// generate random iv
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND);






   $crypted_priv= rtrim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $privKey, MCRYPT_MODE_CBC, $iv)), "\0\3");
   $crypted_pub= rtrim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $pubKey, MCRYPT_MODE_CBC, $iv)), "\0\3");



?>

UPDATE: I replaced ECB with CBC and hope its correct...

Lithilion
  • 1,097
  • 2
  • 11
  • 26

2 Answers2

1

You are not getting the public key with openssl_pkey_get_details(). That structure contains both the public exponent e and private exponent d. It is normal that the private key also contains the public exponent. Most of the time that is a static value (such as 65537, the fourth number of Fermat).

According to the documentation of openssl_pkey_new you can get to the public key using the method openssl_pkey_new():

openssl_pkey_new() generates a new private and public key pair. The public component of the key can be obtained using openssl_pkey_get_public().

That's not the only thing that goes wrong though:

  1. You are not using AES. Rijndael with a block size of 256 is not AES. AES has a block size of 128 bits.
  2. Although mcrypt always expects an IV, ECB mode does not - but read on.
  3. ECB mode is not secure for anything other than random data, you should be using CBC mode to encrypt asymmetric keys (as they almost always contain a structure that may leak information); CBC mode does require a random IV.
  4. You are using the ASCII representation of a string instead of an AES key; you should use a Password Based Key Derivation function such as PBKDF2, bcrypt or scrypt instead. PHP mcrypt is far too forgiving regarding insecure keys.

Note that in general I would also advise a padding mode such as PKCS#7. Mcrypt however does not implement any sane padding method, so you would have to implement that yourself.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • On the other hand, you did specify a sane hash method, a well balanced RSA key size and base64 encoding for the ciphertext :) – Maarten Bodewes Aug 19 '13 at 23:11
  • Thanks for the answer but can you please give me an example. – Lithilion Aug 19 '13 at 23:17
  • An example of what precisely? Please try and create a CBC encrypted private key with the hints I gave you. Ask questions if you get stuck, but note that there is a lot of code already available on Stackoverflow (and other sites). – Maarten Bodewes Aug 19 '13 at 23:57
  • 2
    Note that CBC is vulnerable to padding attacks. Authenticated modes are a better choice. – SLaks Aug 20 '13 at 00:09
  • But you said to me the code I displayed before is not generating a public key. Or this is not the real public key. How can I fix that? – Lithilion Aug 20 '13 at 12:43
  • @SLaks true but that depends on how the ciphertext is used. Mcrypt does not seem to support authenticated mides. And as the underlying libs have not been maintained for about 6 years, they probably never will... – Maarten Bodewes Aug 20 '13 at 14:06
1

There are already formats for storing private keys encrypted. eg.

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,E3B1C06E0D0C2633

gvmXzl6W7eV1a3N5rQNwBWKY9on3IgxZudS33cip5f88FotsPSDJMvqj6LVw2RxobDjhlOOzqmTb
VrlTnoQ6CogXFZSfiPmixiyyptCUEKJkSiEhYGM5GQm0OoGcLeLbgBb9tRpWh5IlXulKD6XFhx8q
/eGg5a+mSkX1i7kv2+Ih3jHmEKwrnfzhcA29pBF3OQJo+Ks9IYneuk676pHtsIs7CpFKq1tDvD8Q
O7URxnVnHLltaFvIxshqyZu92xbUYZR7YzjXl5+3w4TVgeAHUogEV+H9iZTosD/copUsbQO+78w2
E1D3iDS94wRgx0Tjv4xlwrTpOV38FS5rdL32492DcCRlCYM4VtuwjYeWi5shJg69jCb0EwGRqfAo
xko+lbKWELTuFKwD7n1rc/2fTarbGuf8S2AEggBLZyfXHC/9N84mXLFO2XKq+0WdiEFhQj2Cze+a
9qcSK6tPSrjK1LPlnOOppFgDElZaZ0rxsgjtiWSIAEw/Ad+SIM5u+vqwzF8J317JlsdKoBFDw8mS
MxCMuMksKJ23mgvY+THRIVgH3E7lEDZQzCi1Uy6ldLJcran/6wHwP88pVM2odiHkpnrJGcEBbbIk
qsxJZhFT8aUt/cUEBj3fnP7cxoNLQfTHMPqUTqKBWaVufFzGU9YB1R+XWFULLddwJHnV7gPheBlk
MDapowb+Is77+a9Y2VDsOXEvNpqTY0giiSrckG05IZnrhJ24JnSCwyNd99lm7XKdEGGrjBCMqIyI
Fqox8Ahkv3KWAJPYK1eOCc5d/KwZHlnlFJq7ZYy9u3fEnxQCjOEmeXLkLangKA==
-----END RSA PRIVATE KEY-----

...or stronger yet...

PuTTY-User-Key-File-2: ssh-rsa
Encryption: aes256-cbc
Comment: phpseclib-generated-key
Public-Lines: 3
AAAAB3NzaC1yc2EAAAADAQABAAAAgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4
eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RK
NUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDy
R4e9T04ZZw==
Private-Lines: 7
llx04QMegql0/nE5RvcJSrGrodxt6ytuv/JX2caeZBUyQwQc2WBNYagLHyHPM9jI
9OUWz59FLhjFXZMDNMoUXxVmjwQpOAaVPYNxxFM9AF6/NXFji64K7huD9n4A+kLn
sHwMLWPR5a/tZA0r05DZNz9ULA3mQu7Hz4EQ8ifu3uTPJuTmL51x6RmudYKysb20
fM8VzC3ukvzzRh0pujUVTr/yQdmciASVFnZlt4xQy+ZEOVUAOfwjd//AFfXTvk6x
7A45rNlU/uicHwLgoY1APvRHCFxw7F+uVW5L4mSX7NNzqBKkZ+1qpQTAfQvIfEIb
444+CXsgIyOpqt6VxJH2u6elAtE1wau3YaFR8Alm8m97rFYzRi3oDP5NZYkTCWSV
EOpSeghXSs7IilJu8I6/sB1w5dakdeBSFkIynrlFXkO0uUw+QJJWjxY8SypzgIuP
DzduF6XsQrCyo6dnIpGQCQ==
Private-MAC: 35134b7434bf828b21404099861d455e660e8740

You should stick with an already standardized format rather than trying to make your own up.

And why are you encrypting the public key? As the name implies the public key is kinda supposed to be public ;)

neubert
  • 15,947
  • 24
  • 120
  • 212