locked
Importing an rsa private key throws exception

    Question

  • Hello I'm trying to put into our metro app the decryption code that comes from legacy code. It's based on the encryption of a RSA private key, which in final is used to decrypt actual data.

    So far I've got the first part working, decrypting the RSA key using SymmetricKeyAlgorithmProvider, CryptographicKey, CryptographicEngine, CrypotographicBuffer.

    In my IBuffer, I have something like this:

    -----BEGIN RSA PRIVATE KEY-----
    MIICXAIBAAKBgQCB3K727e0ThKVV68fN5J8OQzUSWgn8UdY5Ty9LwKgh1oUO1VA8cT7w/hAgQYmc
    xYDOeT1KdC5/5dS6TaysFooUyxwHg8mo+FEefR6wa0EL4kmggr8MC3Lutj2TC/zvjjJnXgB8L/Jf
    ...
    g023/f3KbzFcgYxayHBOHLt+kmS0ChM1ebPxDlcRxZq/NUipBxM=
    -----END RSA PRIVATE KEY-----

    My problem now is that the following code breaks on exception, where decrypted is the IBUffer with the above content.

    AsymmetricKeyAlgorithmProvider^ rsa = AsymmetricKeyAlgorithmProvider::OpenAlgorithm(L"RSA_OAEP_SHA1");
    CryptographicKey^ key1 = rsa->ImportKeyPair(decrypted);
    The exception message is : "An error occurred during encode or decode operation.\r\n"

    I tried the other OAEP algorithms and the ImportKeyPair(decrypted, CryptographicPrivateKeyBlobType::Pkcs8RawPrivateKeyInfo) variant with no success.

    I guess I am wrong in the assumption that ImportKeyPair can do what I'm trying to do, or is there a bug in OEAP key importation?

    As a side notice, the CryptoWinRT sample also breaks on exception with RSA_OAEP_xxxx in scenario 7.


    Tuesday, July 3, 2012 4:30 PM

Answers

  • Try decoding the base 64 first, and then using  ImportKeyPair( decrypted, CryptographicPrivateKeyBlobType::Pkcs1RsaPrivateKey)

    Probably the ImportKeyPair does not expect base64 encoded data.   It looks like you have PKCS#1 encoded private key.

    Reasoning:

    I see your BASE64 encoded data which decodes to:

     

    30 82 02 5c    universal Sequence of len 25c
    02 01 00        universal Integer of len 1 , val=0    (version)
    02 81 81        universal Integer of len 81 , val=    (Public Modulus)

    00 81 dc ae f6 ed ed 13 84 a5 55 eb c7 cd e4 9f 0e 43 35 12 5a 09 fc 51 d6 39 4f 2f 4b c0 a8 21 d6 85 0e d5 50 3c 71 3e f0 fe 10 20 41 89 9c c5 80 ce 79 3d 4a 74
    2e 7f e5 d4 ba 4d ac ac 16 8a 14 cb 1c 07 83 c9 a8 f8 51 1e 7d 1e b0 6b 41 0b e2 49 a0 82 bf 0c 0b 72 ee b6 3d 93 0b fc ef 8e 32 67 5e 00 7c 2f f2 5f

    ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee   (Data was missing)

    Now AsymmetricKeyAlgorithmProvider.ImportKeyPair  ( http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh967858.aspx )

    supports these data formats: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.security.cryptography.core.cryptographicprivatekeyblobtype.aspx

    Now that looks like the start of a PKCS#1 private key

    http://tools.ietf.org/html/rfc3447

      RSAPrivateKey ::= SEQUENCE {
              version           Version,
              modulus           INTEGER,  -- n
              publicExponent    INTEGER,  -- e
              privateExponent   INTEGER,  -- d
              prime1            INTEGER,  -- p
              prime2            INTEGER,  -- q
              exponent1         INTEGER,  -- d mod (p-1)
              exponent2         INTEGER,  -- d mod (q-1)
              coefficient       INTEGER,  -- (inverse of q) mod p
              otherPrimeInfos   OtherPrimeInfos OPTIONAL
          }

       The fields of type RSAPrivateKey have the following meanings:

        * version is the version number, for compatibility with future
          revisions of this document.  It shall be 0 for this version of the
          document, unless multi-prime is used, in which case it shall be 1.

                Version ::= INTEGER { two-prime(0), multi(1) }
                   (CONSTRAINED BY
                   {-- version must be multi if otherPrimeInfos present --})

        * modulus is the RSA modulus n.

    Tuesday, July 3, 2012 8:41 PM

All replies

  • Try decoding the base 64 first, and then using  ImportKeyPair( decrypted, CryptographicPrivateKeyBlobType::Pkcs1RsaPrivateKey)

    Probably the ImportKeyPair does not expect base64 encoded data.   It looks like you have PKCS#1 encoded private key.

    Reasoning:

    I see your BASE64 encoded data which decodes to:

     

    30 82 02 5c    universal Sequence of len 25c
    02 01 00        universal Integer of len 1 , val=0    (version)
    02 81 81        universal Integer of len 81 , val=    (Public Modulus)

    00 81 dc ae f6 ed ed 13 84 a5 55 eb c7 cd e4 9f 0e 43 35 12 5a 09 fc 51 d6 39 4f 2f 4b c0 a8 21 d6 85 0e d5 50 3c 71 3e f0 fe 10 20 41 89 9c c5 80 ce 79 3d 4a 74
    2e 7f e5 d4 ba 4d ac ac 16 8a 14 cb 1c 07 83 c9 a8 f8 51 1e 7d 1e b0 6b 41 0b e2 49 a0 82 bf 0c 0b 72 ee b6 3d 93 0b fc ef 8e 32 67 5e 00 7c 2f f2 5f

    ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee   (Data was missing)

    Now AsymmetricKeyAlgorithmProvider.ImportKeyPair  ( http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh967858.aspx )

    supports these data formats: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.security.cryptography.core.cryptographicprivatekeyblobtype.aspx

    Now that looks like the start of a PKCS#1 private key

    http://tools.ietf.org/html/rfc3447

      RSAPrivateKey ::= SEQUENCE {
              version           Version,
              modulus           INTEGER,  -- n
              publicExponent    INTEGER,  -- e
              privateExponent   INTEGER,  -- d
              prime1            INTEGER,  -- p
              prime2            INTEGER,  -- q
              exponent1         INTEGER,  -- d mod (p-1)
              exponent2         INTEGER,  -- d mod (q-1)
              coefficient       INTEGER,  -- (inverse of q) mod p
              otherPrimeInfos   OtherPrimeInfos OPTIONAL
          }

       The fields of type RSAPrivateKey have the following meanings:

        * version is the version number, for compatibility with future
          revisions of this document.  It shall be 0 for this version of the
          document, unless multi-prime is used, in which case it shall be 1.

                Version ::= INTEGER { two-prime(0), multi(1) }
                   (CONSTRAINED BY
                   {-- version must be multi if otherPrimeInfos present --})

        * modulus is the RSA modulus n.

    Tuesday, July 3, 2012 8:41 PM
  • Thanks a lot, that is a dense and valuable pack of informations!

    I'll check the points you put in light.

    Wednesday, July 4, 2012 2:27 PM
  • Many thanks : decoding the base64 content, putting it in an IBuffer and ImportingKeyPair from that buffer worked!
    Wednesday, July 4, 2012 3:33 PM
  • HELP,你能给我一个示例吗,将私钥里面的

              modulus           INTEGER,  -- n
              publicExponent    INTEGER,  -- e
              privateExponent   INTEGER,  -- d
              prime1            INTEGER,  -- p
              prime2            INTEGER,  -- q
              exponent1         INTEGER,  -- d mod (p-1)
              exponent2         INTEGER,  -- d mod (q-1)
              coefficient       INTEGER,  -- (inverse of q) mod p

    转换为一个IBUFFER吗?我拼接出来的导不进去。

    Friday, December 26, 2014 6:38 AM