Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImportKey from RSAPrivateKey #233

Closed
miguelrvs opened this issue Jun 7, 2019 · 5 comments
Closed

ImportKey from RSAPrivateKey #233

miguelrvs opened this issue Jun 7, 2019 · 5 comments
Assignees

Comments

@miguelrvs
Copy link

miguelrvs commented Jun 7, 2019

I know this is a loooong closed thread, but I managed to open the PKCS#8 and extract the private key down to it's components. Also I could crate a RSAPrivateKey object using them as ctor arguments.
I am a step after #53, since @alfredomova could not extract the key from PKCS#8.

This code produces the following screen:

const pkcs8bag = new PKCS8ShroudedKeyBag({ schema: asn1.result });
await pkcs8bag.parseInternalValues({password: p});
let rsakey = new RSAPrivateKey( pkcs8bag.parsedValue.parsedKey );

Spectacle u23231
Now I have the components (modulus, exponents, et. al.) from the RSA key.

My question is: how do I import that RSAPrivateKey into web cryptoAPI (using importKey)?

I have already tried to import it directly, and also as BER.

const pkcs8bag = new PKCS8ShroudedKeyBag({ schema: asn1.result });
await pkcs8bag.parseInternalValues({password: p});
let ber = pkcs8bag.parsedValue.toSchema().toBER();
return crypto.subtle.importKey("pkcs8", ber, {name:"RSA-OAEP"}, true, ['encrypt', 'decrypt', 'sign', 'verify']);
...
return crypto.subtle.importKey("pkcs8", ber, {name:"RSASSA-PKCS1-v1_5"}, true, ['encrypt', 'decrypt', 'sign', 'verify']);
...
return crypto.subtle.importKey("pkcs8", ber, {name:"RSA-OAEP"}, true, ['encrypt', 'decrypt', 'sign', 'verify']);

But continue getting: "DataError: Data provided to an operation does not meet requirements"
Meanwhile OpenSSL produces this:

 $ openssl pkcs8 -inform der -in AAA010101AAA_FIEL.key |openssl asn1parse -i
    0:d=0  hl=4 l= 631 cons: SEQUENCE          
    4:d=1  hl=2 l=   1 prim:  INTEGER           :00
    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      [HEX DUMP]:3082025D020100028181009207A1492CBE5BD71E...

If anyone can point me how do I import (maybe needs conversion) that RSAPrivateKey into web cryptoAPI (using importKey)?

@YuryStrozhevsky
Copy link
Collaborator

@miguelrvs Not sure what was wrong in the "looong closed thread", but in your case you are working with incorrect data type.

Looong time ago WebCrypto API has a full support for importing PKCS#8 keys. But not at all platforms - Safari had no such support. In order to cover all platforms I made a special layer handling all possible situations of importing/exporting key via JWK. In case of PKCS#8 the code is here. Probably you will find the code helpful. But back to you specific question: PKCS#8 works with PrivateKeyInfo data type, not RSAPrivateKey.

@miguelrvs
Copy link
Author

Yes Yury; I think I'm using the PrivateKeyInfo here:

let ber = pkcs8bag.parsedValue.toSchema().toBER();

Thanks your your sugestion, will test importing via CryptoEngine.importKey() instead of directly use of crypto.subtle.importKey().

In either case, forgot to attach the files I'm using.
Cert_Sellos.zip
These files are public domain and the password is "12345678a"

@YuryStrozhevsky
Copy link
Collaborator

YuryStrozhevsky commented Jun 8, 2019

@miguelrvs Also you were using incorrect options during importKey - please use decrypt only. Or decrypt and verify - depends on your tasks. I bet the DOMException is mostly because of it.

@miguelrvs
Copy link
Author

miguelrvs commented Jun 11, 2019

@YuryStrozhevsky used decrypt , sign and verify , each alone, and the error was similar.

const pkcs8bag = new PKCS8ShroudedKeyBag({ schema: asn1.result });
await pkcs8bag.parseInternalValues({password: p});
this.CryptoEngine = new CryptoEngine({crypto:crypto, subtle:crypto.subtle});
return this.CryptoEngine.importKey("pkcs8", pkcs8bag.parsedValue, {name:"RSASSA-PKCS1-v1_5", hash:{name:'SHA-1'}}, true, ['decrypt']);

gives: Incorrect keyData DataError: Data provided to an operation does not meet requirements

Also:

const pkcs8bag = new PKCS8ShroudedKeyBag({ schema: asn1.result });
await pkcs8bag.parseInternalValues({password: p});
this.CryptoEngine = new CryptoEngine({crypto:crypto, subtle:crypto.subtle});
return this.CryptoEngine.importKey("pkcs8", pkcs8bag.parsedValue, {name:"RSASSA-PKCS1-v1_5", hash:{name:'SHA-1'}}, true, ['sign']);

Gives the same: Incorrect keyData DataError: Data provided to an operation does not meet requirements.

(verify gives the same error).

Unfortunately I have used way more the time alloted to this project; will continue experimenting when have some time to spare. Thanks for your help

@YuryStrozhevsky
Copy link
Collaborator

@miguelrvs I have checked your data. Not sure why, but private key data in your example was trancated. This is how your data looks like after decoding:

SEQUENCE {
  INTEGER 0
  SEQUENCE {
    OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
    NULL
    }
  OCTET STRING, encapsulates {
    SEQUENCE {
      INTEGER 0
      INTEGER
        00 92 07 A1 49 2C BE 5B D7 1E 5F F7 A5 3A 24 D2
        DA B6 92 A3 10 CC 19 4A 5A FE E4 8B DC 90 4D B8
        B0 19 E4 D7 CD 7C 0E DE 3C 8A 63 4C 7E 7D BB EC
        49 79 83 BF 6B AB 97 6D 9D 4A 8A D4 6C B4 D2 73
        9B 60 DB C1 61 26 90 7F 57 F2 3C 93 BE 8D 9F A6
        19 15 3C 79 2E C5 0D 0B 4B 4C FB 43 37 83 EB F0
        8F F5 39 B9 02 BF 35 26 B9 37 A2 86 1D E8 F5 2A
        7F 6C 0C B0 D1 57 88 23 7B 0D 20 4C 7E B6 BF E8
        19
      INTEGER 65537
      INTEGER
        73 80 DF 7C 9E 8C 6E DE 27 23 67 20 E4 6D 8D ED
        FA EC DF 58 00 E7 9C 1D 7F 71 4C 83 08 0C C1 A1
        60 C9 D6 3B AC FD A1 A0 A7 21 45 B6 E3 42 C9 F1
        8F D0 BA 8E B2 69 93 05 0F 99 E1 CD 9D F4 BC 05
        1A 23 67 1B D8 9E 6B 34 AC 65 60 A5 88 3A CD 41
        F1 BD 54 E2 83 B5 C2 30 F8 0D ED 01 44 B1 87 85
        76 6B 4A C5 70 5E 77 D8 B7 3C 0C 7E 55 94 3D C1
        8E 8C DE 32 42 CD F2 69 26 7A 03 B5 83 56 13 65
      INTEGER
        00 E8 BB C3 DB 5A 20 B1 E9 D4 45 5F F7 74 EA B1
        4F 1F 0C D0 9E 4F A5 3D 66 21 B8 9A 30 D6 DF 24
        B9 D2 6C C5 38 51 AD D7 A9 49 54 6F FA 44 F4 8C
        69 53 00 B8 8B EB 15 A4 F0 8A 93 85 61 DB 57 9F
        BF
      INTEGER
        00 A0 A0 E6 77 DE 46 03 64 AF B6 4B 6A 02 9F FA
        D0 B1 64 04 D6 49 70 EB DD 1B A8 F6 51 87 FB 6F
        A7 44 F2 6E 19 B2 28 FF 03 22 7A 23 C7 12 6B B7
        E6 B2 30 77 8D 4F 2B A2 83 55 B4 FD D5 92 DD EE
        27
      INTEGER
        00 AD 7D 3A D5 4B 6C 4F F3 F5 0E FA 28 E7 79 04
        4F EC DF 8A AC 58 C6 DE EC 41 7A F1 46 33 07 08
        C3 94 BF 0C 8D 9D 25 B0 3C 3B B3 BB FD 9E 65 86
        3E 05 67 E6 2A 37 46 5D 3C 0A B1 49 9E D6 F9 8C
        D5
      INTEGER
        34 FB 7D A9 92 2E 83 D6 05 43 5A F2 B7 B4 EF 35
        41 1D DD 9E 95 10 E3 2B C6 80 DF E6 9A B4 EB EA
        3F 8A BB 98 4C 34 CB 90 CC 21 7F 85 9D 64 DC 7F
        02 CD 8B D1 97 88 AC 0D 28 0B 10 23 0F 53 96 C7
      INTEGER
        00 D4 2A 1B E1 F0 E0 CC FB DC 88 17 FD 8E B8 8A
        97 16 5F 81 3F 90 83 F2 55 25 87 3A 4A 6F CE ED
        17 57 E5 41 6F E1 9D F0 FF 7E 9C CF 50 5D 4A 89
        27 CD 25 9D A9 F3 69 46 0C 50 10 50 95 D0 4F 13
        51
      }
    }
  }

This is how SHA-1 private key from this example looks like:

SEQUENCE {
  INTEGER 0
  SEQUENCE {
    OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
    NULL
    }
  OCTET STRING, encapsulates {
    SEQUENCE {
      INTEGER 0
      INTEGER
        00 CD 2B 3E 82 E4 0C FC EF 0C 86 D3 1C 31 AF AE
        A2 72 75 B3 9B AF 74 8B 4A 9C E2 E3 75 61 1F 2D
        10 DF D4 FA 63 8A 89 52 FF 23 5C 0B 4A 26 7B DD
        4C 0F CB 0A EC F4 6C 33 97 8C 8E 37 A7 77 20 E2
        12 59 98 58 F5 CF 1C 0D DD 9C F0 14 D6 21 43 AC
        C2 DE 0F 64 BC 0C 8A 38 1D 4D 44 D9 1F F7 80 F3
        2A 54 BE 8E 6D E7 A4 6B 32 49 D4 CD 01 04 DD 62
        32 E3 03 BB DC 58 16 74 D4 7E 26 26 0D AE 83 30
                [ Another 129 bytes skipped ]
      INTEGER 65537
      INTEGER
        09 2A 2E DB 2A F3 B7 92 B8 15 07 B6 21 34 0F 51
        7B 5A 6D A0 FD 37 F0 06 EF B6 24 E1 F7 EA 2C 19
        AE 5D F5 A7 5F A7 5D B9 3E EB 9C 27 7E 4B 97 29
        90 25 0A 42 66 72 B4 E5 46 A6 8D AE E1 DF EA A9
        56 2E 3B 7F 13 76 D5 D9 B9 EA 71 8B D5 25 90 40
        8E 29 D2 DE A1 92 C5 09 EE 0B 2E C5 C2 49 14 D3
        A5 C0 73 5D 4E 75 26 42 B3 50 99 AD BB 79 66 2B
        0E BF FA 72 CF CE 84 FE 7E FA 16 46 13 2F 12 0B
                [ Another 128 bytes skipped ]
      INTEGER
        00 E8 65 C6 BA F5 74 EC E4 02 78 83 39 7E C0 64
        72 67 A9 C2 B4 55 CF A4 4B 26 8F 11 31 7B F3 74
        FA 2B 24 DA 26 88 EC 82 2E 92 96 C5 A3 BA FA 4B
        C1 90 D7 E7 2A AB 37 56 3C 90 88 F6 31 F0 C9 68
        A1 0C B0 0B 3D DA CD 3C 6F FF F3 A5 FE 81 C9 00
        36 F4 B1 79 B7 CB 15 80 88 3A AA 3C 0A 2E 19 97
        99 35 BA 67 44 F3 DB FF 8C A5 D8 EE 92 54 57 83
        0A 27 3A B6 7B 1E 5D 27 EF 36 D8 44 0F 41 C0 1C
        AF
      INTEGER
        00 E2 01 89 55 7A CE 49 0A B6 A2 04 2E 69 07 23
        49 58 7C E9 A8 71 7F 58 03 82 32 36 C8 3C 13 6B
        57 91 7A 46 1E BC 5F F4 79 3B 98 B8 39 57 EC 1C
        55 A2 98 11 20 11 D4 21 1D 39 0B A8 45 52 14 22
        32 CF DB 3A 18 7A 5F F4 39 4D 5F 2B D1 0E BA FF
        DE C7 0D 0F 21 ED 75 35 A0 64 15 8D 38 91 66 BB
        F9 52 82 DF 98 1C AE C7 22 F2 32 CF C8 19 E4 2E
        25 00 58 55 96 D5 B2 CD 76 99 DD 77 D6 2C E5 C3
        1F
      INTEGER
        2C 56 16 66 DE A3 32 FA 80 FA 2A D6 D2 36 B4 33
        1B 51 C8 C2 8C C8 73 68 9E EF 96 71 21 5B 9E 0A
        88 26 9C B3 D3 55 83 B4 8C E4 D4 C9 DA C7 1B A2
        CF 16 51 94 D3 5B 58 49 6F AD A1 82 7F 94 7D 30
        94 72 15 82 F4 76 49 3C 78 D1 2B EE F5 25 BA B3
        C1 55 06 8A A8 E4 EE 43 8F 25 A1 14 B4 1C CF CE
        3B F0 D6 F8 D1 A9 3C 04 C2 33 33 B8 98 FC A5 14
        4F CD A4 B8 B2 5F 45 5A 1E D5 7D 8E 87 95 B6 23
      INTEGER
        00 9C 0F 3F 8B BC FF 10 C4 CB 13 D9 1B 4A FE D8
        C8 DE C7 72 79 13 D6 41 2A 3B 0E FD 71 0A BA C6
        16 73 A8 21 1F 3C 28 6E 22 00 9B 16 2A D2 A1 81
        77 48 8D 04 D6 46 39 5A 9C 59 35 C9 7E 04 8D 4E
        88 13 AB 67 D4 5B 3C 42 E2 06 A1 3F 1A 5E B7 95
        D3 79 53 75 2D 92 50 AB 35 13 A7 26 1A F7 9C 1F
        14 AC 7B 1E 76 64 E7 F3 2E 18 5C 29 CA 1C C6 C9
        6E 57 6C A7 BD 3D D6 F7 B5 7B CD C7 E0 26 A4 89
        35
      INTEGER
        00 E7 11 75 C2 3C 34 61 03 AD 91 C7 DB 61 30 C6
        51 30 00 AF 6E 67 DA F6 56 DE F9 C3 60 98 E1 94
        F7 56 45 6C 9E FD 00 FD B9 71 30 07 A6 AF 12 43
        78 9D 24 5F 56 64 6A BF F7 D4 21 3F 0A 98 4D A1
        78 65 3A 99 39 7C 3E C8 5E 55 8B 47 65 9C DC 72
        D4 3E 88 20 D3 F3 C0 08 63 0D 50 AE 4D 5D AA 51
        CF 3C 08 A2 11 4C D9 F5 30 F5 F5 29 B7 8A 08 DC
        8B 7B F6 27 9C 62 7D F7 55 6F 10 85 6C A8 29 65
        C2
      }
    }
  }

I did not dig too deeper, but most probably because the data was trancated the import was failed. So, I do recommend you to check your initial data using OpenSSL, for example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants