diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 82ec4c35..8d96c132 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -191,6 +191,10 @@ define('CRYPT_RSA_PRIVATE_FORMAT_PUTTY', 1); * XML formatted private key */ define('CRYPT_RSA_PRIVATE_FORMAT_XML', 2); +/** + * PKCS#8 formatted private key + */ +define('CRYPT_RSA_PRIVATE_FORMAT_PKCS8', 3); /**#@-*/ /**#@+ @@ -846,6 +850,17 @@ class Crypt_RSA $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); + if ($this->privateKeyFormat == CRYPT_RSA_PRIVATE_FORMAT_PKCS8) { + $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA + $RSAPrivateKey = pack('Ca*a*Ca*a*', + CRYPT_RSA_ASN1_INTEGER, "\01\00", $rsaOID, 4, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); + $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); + $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" . + chunk_split(base64_encode($RSAPrivateKey), 64) . + '-----END PRIVATE KEY-----'; + return $RSAPrivateKey; + } + if (!empty($this->password) || is_string($this->password)) { $iv = crypt_random_string(8); $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key @@ -993,6 +1008,7 @@ class Crypt_RSA } return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false; case CRYPT_RSA_PRIVATE_FORMAT_PKCS1: + case CRYPT_RSA_PRIVATE_FORMAT_PKCS8: case CRYPT_RSA_PUBLIC_FORMAT_PKCS1: /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to @@ -1083,7 +1099,9 @@ class Crypt_RSA 7:d=1 hl=2 l= 13 cons: SEQUENCE 9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption 20:d=2 hl=2 l= 0 prim: NULL - 22:d=1 hl=4 l= 609 prim: OCTET STRING */ + 22:d=1 hl=4 l= 609 prim: OCTET STRING + + ie. PKCS8 keys*/ if ($tag == CRYPT_RSA_ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") { $this->_string_shift($key, 3);