locked
BCryptImportKeyPair returns bad data when trying to import X.509 public key RRS feed

  • Question

  • I'm trying to write some sample code that has to eventually run in kernel mode. Since there are no X.509 certificate parsers that run in kernel mode, I've to write my own custom parser. The issue I have now is that I'm trying to import a public key contained in an X.509 certificate. For testing purposes, I exported a google certificate in my browser's store to a DER file. I had no idea what bytes represented the public key (1024 bits) so I used CertCreateCertificateContext and CryptImportPublicKeyInfoEx2 to determine the same and was able to get a key handle.

    Here’s a snippet that now tries to import the key, using BCryptImportKeyPair, represented in the following array:

    BYTE key[] = {
    0×30,0×81,0×89,0×02,0×81,0×81,0×00,0xbf,0xcb,0xb8
    ,0×10,0×20,0xd0,0×17,0×54,0x4c,0xab,0xb9,0×49,0x5a
    ,0xa8,0×03,0xdc,0xad,0×74,0xa7,0xb3,0×26,0×49,0×48
    ,0x7e,0xeb,0×67,0×21,0xf9,0xf6,0xfe,0×70,0×30,0xf3
    ,0xf4,0x4e,0xe6,0×47,0xf1,0xf7,0xa1,0×11,0×59,0×75
    ,0x1e,0xa0,0x0f,0xc5,0×77,0xf6,0xe4,0xdd,0xdc,0x4b
    ,0x9e,0×12,0×99,0x7b,0x5e,0xf3,0xc4,0×10,0×97,0×73
    ,0xfc,0x7f,0xd0,0×64,0xec,0×69,0xeb,0×62,0×08,0xea
    ,0x0e,0×04,0xc1,0x1f,0xbf,0xd3,0×19,0×52,0xfe,0xaa
    ,0×80,0×61,0xf8,0×40,0x9f,0x5b,0×96,0xff,0xea,0xd4
    ,0×87,0xbc,0xc9,0x5b,0×61,0xb6,0xc4,0×62,0×45,0x6b
    ,0×66,0xf6,0xb1,0×20,0x8d,0xe4,0×27,0×59,0×81,0xac
    ,0×28,0xcd,0xc7,0xd2,0×60,0x1c,0x0b,0xfa,0x08,0xce
    ,0xa3,0×85,0xd0,0xe5,0x3f,0x02,0x03,0x01,0x00,0x01}; //140 bytes

    //open an algorithm handle
    if(!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(
    &hSignAlg,
    BCRYPT_RSA_ALGORITHM,
    MS_PRIMITIVE_PROVIDER,
    0
    )))
    {
    wprintf(L”**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n”, status);
    goto Cleanup;
    }

    if(!NT_SUCCESS(status = BCryptImportKeyPair(
    hSignAlg,
    NULL,
    BCRYPT_RSAPUBLIC_BLOB,
    &hTmpKey,
    key,
    140,
    0)))
    {
    wprintf(L”**** Error 0x%x returned by BCryptImportKeyPair\n”, status);
    PrintError(status);
    goto Cleanup;
    }

    This returns bad data. Reversing the key array did not help either. I also tried using LEGACY_RSAPUBLIC_BLOB.

    Any ideas to what I could be doing wrong? I’d really appreciate all the help I can get.

    Sunday, February 12, 2012 11:26 AM

Answers

  • Check out    "BCRYPT_RSAKEY_BLOB structure "

    http://msdn.microsoft.com/en-us/library/windows/desktop/aa375531(v=vs.85).aspx

    52 53 41 31    magic RSA1
    00 04 00 00    bitlen = 1024
    03 00 00 00    cbPublicExp = 3
    80 00 00 00    cbModulus = 128
    00 00 00 00    cprime1 unused
    00 00 00 00    cprime1 unused
    01 00 01       PublicExponent[cbPublicExp] // Big-endian.

    bf cb b8 10 20 d0 17 54 4c ab b9 49 5a a8 03 dc
    ad 74 a7 b3 26 49 48 7e eb 67 21 f9 f6 fe 70 30
    f3 f4 4e e6 47 f1 f7 a1 11 59 75 1e a0 0f c5 77
    f6 e4 dd dc 4b 9e 12 99 7b 5e f3 c4 10 97 73 fc
    7f d0 64 ec 69 eb 62 08 ea 0e 04 c1 1f bf d3 19
    52 fe aa 80 61 f8 40 9f 5b 96 ff ea d4 87 bc c9
    5b 61 b6 c4 62 45 6b 66 f6 b1 20 8d e4 27 59 81
    ac 28 cd c7 d2 60 1c 0b fa 08 ce a3 85 d0 e5 3f               Modulus[cbModulus] // Big-endian.

    • Marked as answer by jrrtolkienfan Monday, February 13, 2012 5:45 AM
    Monday, February 13, 2012 3:38 AM

All replies

  • Guess I wasn't using the correct bytes. Apparently just using the modulus bytes prefixed with

    0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01

    works. I know what the first 8 and last 4 bytes mean but I've no idea what the other bytes mean nor what data structure they represent. Any ideas?

    Sunday, February 12, 2012 2:40 PM
  • Check out    "BCRYPT_RSAKEY_BLOB structure "

    http://msdn.microsoft.com/en-us/library/windows/desktop/aa375531(v=vs.85).aspx

    52 53 41 31    magic RSA1
    00 04 00 00    bitlen = 1024
    03 00 00 00    cbPublicExp = 3
    80 00 00 00    cbModulus = 128
    00 00 00 00    cprime1 unused
    00 00 00 00    cprime1 unused
    01 00 01       PublicExponent[cbPublicExp] // Big-endian.

    bf cb b8 10 20 d0 17 54 4c ab b9 49 5a a8 03 dc
    ad 74 a7 b3 26 49 48 7e eb 67 21 f9 f6 fe 70 30
    f3 f4 4e e6 47 f1 f7 a1 11 59 75 1e a0 0f c5 77
    f6 e4 dd dc 4b 9e 12 99 7b 5e f3 c4 10 97 73 fc
    7f d0 64 ec 69 eb 62 08 ea 0e 04 c1 1f bf d3 19
    52 fe aa 80 61 f8 40 9f 5b 96 ff ea d4 87 bc c9
    5b 61 b6 c4 62 45 6b 66 f6 b1 20 8d e4 27 59 81
    ac 28 cd c7 d2 60 1c 0b fa 08 ce a3 85 d0 e5 3f               Modulus[cbModulus] // Big-endian.

    • Marked as answer by jrrtolkienfan Monday, February 13, 2012 5:45 AM
    Monday, February 13, 2012 3:38 AM
  • Thanks Andrew. That explains it. I'd looked at this structure before. Guess I didn't read the description well enough.
    Monday, February 13, 2012 5:45 AM