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

Use RSAPublicKey in 0x1205 #233

Merged
merged 1 commit into from
Sep 30, 2021
Merged

Conversation

clehner
Copy link
Contributor

@clehner clehner commented Sep 28, 2021

This PR is to change the rsa-x509-pub (0x1205) entry to use RSAPublicKey (instead of SubjectPublicKeyInfo), and to rename it to rsa-pub.
This is to have a more compact and unambiguous key representation, and greater consistency with the other public key types, by removing the wrapper data structure that includes an algorithm identifier.

@b5, @expede (and anyone else): are you already using the current rsa-x509-pub/0x1205, such that this would break your existing installations and credentials?
If so, we could probably use a new code instead of changing this one. But I think it would be useful to have somewhat of a canonical representation of the key type in the table. Also, backwards compatibility with the previous usage would be possible, as these two representations are distuinguishable by their data structure, either by inspecting the bytes, inspecting the parsed data structure, or using libraries and a try-parse approach as mentioned by @rvagg in #230 (comment). See below for two examples of RSAPublicKey, for potential test vector purposes (#232), followed by an example of SubjectPublicKeyInfo, for comparison.

Example 1

Base64-encoded value for RSAPublicKey with a 2048-bit modulus:

MIIBCgKCAQEAsbX82NTV6IylxCh7MfV4hlyvaniCajuP97GyOqSvTmoEdBOflFvZ06kR/9D6ctt4
5Fk6hskfnag2GG69NALVH2o4RCR6tQiLRpKcMRtDYE/thEmfBvDzm/VVkOIYfxu+Ipuo9J/S5XDN
Djczx2v+3oDh5+CIHkU46hvFeCvpUS+L8TJSbgX0kjVk/m4eIb9wh63rtmD6Uz/KBtCo5mmR4TEt
cLZKYdqMp3wCjN+TlgHiz/4oVXWbHUefCEe8rFnX1iQnpDHU49/SaXQoud1jCaexFn25n+Aa8f8b
c5Vm+5SeRwidHa6ErvEhTvf1dz6GoNPp2iRvm+wJ1gxwWJEYPQIDAQAB

ASN.1 object dump (using dumpasn1):

  0 266: SEQUENCE {
  4 257:   INTEGER
       :     00 B1 B5 FC D8 D4 D5 E8 8C A5 C4 28 7B 31 F5 78
       :     86 5C AF 6A 78 82 6A 3B 8F F7 B1 B2 3A A4 AF 4E
       :     6A 04 74 13 9F 94 5B D9 D3 A9 11 FF D0 FA 72 DB
       :     78 E4 59 3A 86 C9 1F 9D A8 36 18 6E BD 34 02 D5
       :     1F 6A 38 44 24 7A B5 08 8B 46 92 9C 31 1B 43 60
       :     4F ED 84 49 9F 06 F0 F3 9B F5 55 90 E2 18 7F 1B
       :     BE 22 9B A8 F4 9F D2 E5 70 CD 0E 37 33 C7 6B FE
       :     DE 80 E1 E7 E0 88 1E 45 38 EA 1B C5 78 2B E9 51
       :     2F 8B F1 32 52 6E 05 F4 92 35 64 FE 6E 1E 21 BF
       :     70 87 AD EB B6 60 FA 53 3F CA 06 D0 A8 E6 69 91
       :     E1 31 2D 70 B6 4A 61 DA 8C A7 7C 02 8C DF 93 96
       :     01 E2 CF FE 28 55 75 9B 1D 47 9F 08 47 BC AC 59
       :     D7 D6 24 27 A4 31 D4 E3 DF D2 69 74 28 B9 DD 63
       :     09 A7 B1 16 7D B9 9F E0 1A F1 FF 1B 73 95 66 FB
       :     94 9E 47 08 9D 1D AE 84 AE F1 21 4E F7 F5 77 3E
       :     86 A0 D3 E9 DA 24 6F 9B EC 09 D6 0C 70 58 91 18
       :     3D
265   3:   INTEGER 65537
       :   }

JWK:

{
  "kty": "RSA",
  "n": "sbX82NTV6IylxCh7MfV4hlyvaniCajuP97GyOqSvTmoEdBOflFvZ06kR_9D6ctt45Fk6hskfnag2GG69NALVH2o4RCR6tQiLRpKcMRtDYE_thEmfBvDzm_VVkOIYfxu-Ipuo9J_S5XDNDjczx2v-3oDh5-CIHkU46hvFeCvpUS-L8TJSbgX0kjVk_m4eIb9wh63rtmD6Uz_KBtCo5mmR4TEtcLZKYdqMp3wCjN-TlgHiz_4oVXWbHUefCEe8rFnX1iQnpDHU49_SaXQoud1jCaexFn25n-Aa8f8bc5Vm-5SeRwidHa6ErvEhTvf1dz6GoNPp2iRvm-wJ1gxwWJEYPQ",
  "e": "AQAB"
}

Example 2

Base64-encoded value for RSAPublicKey with a 4096-bit modulus:

MIICCgKCAgEAqMCkFFRFWtzUyZeK8mgJdyM6SEQcXC5E6JwCRVDld+jlJs8sXNOE/vliexq34wZR
Q4hk53+JPFlvZ/QjRgIxdUxSMiZ3S5hlNVvvRaue6SMakA9ugQhnfXaWORro0UbPuHLms+bg5StD
P8+8tIezu9c1H1FjwPcdbV6rAvKhyhnsM10qP3v2CPbdE0q3FOsihoKuTelImtO110E7N6fLn4U3
EYbC4OyViqlrP1o/1M+R+tiM1cb4pD7XKJnIs6ryZdfOQSPBJwjNqSdN6Py/tdrFgPDTyacSSdpT
VADOM2IMAoYbhV1N5APhnjOHBRFyKkF1HffQKpmXQLBqvUNNjuhmpVKWBtrTdcCKrglFXiw0cKGH
KxIirjmiOlB/HYHg5UdosyE3/1Txct2U7+WBB6QXak1UgxCzgKYBDI8UPA0RlkUuHHP/Zg0fVXrX
IInHO04MYxUeSps5qqyP6dJBu/v/BDn3zUq6LYFwJ/+xsU7zbrKYB4jaRlHPoCj/eDC+rSA2uQ4K
XHBB8/aAqNFC9ukWxc26Ifz9dF968DLuL30bi+ZAa2oUh492Pw1bg89J7i4qTsOOfpQvGyDV7TGh
KuUG3Hbumfr2w16S+/3EI2RIyd1nYsflE6ZmCkZQMG/lwDAFXaqfyGKEDouJuja4XH8r4fGWeGTr
ozIoniXT1HUCAwEAAQ==

ASN.1 structure:

  0 522: SEQUENCE {
  4 513:   INTEGER
       :     00 A8 C0 A4 14 54 45 5A DC D4 C9 97 8A F2 68 09
       :     77 23 3A 48 44 1C 5C 2E 44 E8 9C 02 45 50 E5 77
       :     E8 E5 26 CF 2C 5C D3 84 FE F9 62 7B 1A B7 E3 06
       :     51 43 88 64 E7 7F 89 3C 59 6F 67 F4 23 46 02 31
       :     75 4C 52 32 26 77 4B 98 65 35 5B EF 45 AB 9E E9
       :     23 1A 90 0F 6E 81 08 67 7D 76 96 39 1A E8 D1 46
       :     CF B8 72 E6 B3 E6 E0 E5 2B 43 3F CF BC B4 87 B3
       :     BB D7 35 1F 51 63 C0 F7 1D 6D 5E AB 02 F2 A1 CA
       :     19 EC 33 5D 2A 3F 7B F6 08 F6 DD 13 4A B7 14 EB
       :     22 86 82 AE 4D E9 48 9A D3 B5 D7 41 3B 37 A7 CB
       :     9F 85 37 11 86 C2 E0 EC 95 8A A9 6B 3F 5A 3F D4
       :     CF 91 FA D8 8C D5 C6 F8 A4 3E D7 28 99 C8 B3 AA
       :     F2 65 D7 CE 41 23 C1 27 08 CD A9 27 4D E8 FC BF
       :     B5 DA C5 80 F0 D3 C9 A7 12 49 DA 53 54 00 CE 33
       :     62 0C 02 86 1B 85 5D 4D E4 03 E1 9E 33 87 05 11
       :     72 2A 41 75 1D F7 D0 2A 99 97 40 B0 6A BD 43 4D
       :     8E E8 66 A5 52 96 06 DA D3 75 C0 8A AE 09 45 5E
       :     2C 34 70 A1 87 2B 12 22 AE 39 A2 3A 50 7F 1D 81
       :     E0 E5 47 68 B3 21 37 FF 54 F1 72 DD 94 EF E5 81
       :     07 A4 17 6A 4D 54 83 10 B3 80 A6 01 0C 8F 14 3C
       :     0D 11 96 45 2E 1C 73 FF 66 0D 1F 55 7A D7 20 89
       :     C7 3B 4E 0C 63 15 1E 4A 9B 39 AA AC 8F E9 D2 41
       :     BB FB FF 04 39 F7 CD 4A BA 2D 81 70 27 FF B1 B1
       :     4E F3 6E B2 98 07 88 DA 46 51 CF A0 28 FF 78 30
       :     BE AD 20 36 B9 0E 0A 5C 70 41 F3 F6 80 A8 D1 42
       :     F6 E9 16 C5 CD BA 21 FC FD 74 5F 7A F0 32 EE 2F
       :     7D 1B 8B E6 40 6B 6A 14 87 8F 76 3F 0D 5B 83 CF
       :     49 EE 2E 2A 4E C3 8E 7E 94 2F 1B 20 D5 ED 31 A1
       :     2A E5 06 DC 76 EE 99 FA F6 C3 5E 92 FB FD C4 23
       :     64 48 C9 DD 67 62 C7 E5 13 A6 66 0A 46 50 30 6F
       :     E5 C0 30 05 5D AA 9F C8 62 84 0E 8B 89 BA 36 B8
       :     5C 7F 2B E1 F1 96 78 64 EB A3 32 28 9E 25 D3 D4
       :     75
521   3:   INTEGER 65537
       :   }

JWK:

{
  "kty": "RSA",
  "n": "qMCkFFRFWtzUyZeK8mgJdyM6SEQcXC5E6JwCRVDld-jlJs8sXNOE_vliexq34wZRQ4hk53-JPFlvZ_QjRgIxdUxSMiZ3S5hlNVvvRaue6SMakA9ugQhnfXaWORro0UbPuHLms-bg5StDP8-8tIezu9c1H1FjwPcdbV6rAvKhyhnsM10qP3v2CPbdE0q3FOsihoKuTelImtO110E7N6fLn4U3EYbC4OyViqlrP1o_1M-R-tiM1cb4pD7XKJnIs6ryZdfOQSPBJwjNqSdN6Py_tdrFgPDTyacSSdpTVADOM2IMAoYbhV1N5APhnjOHBRFyKkF1HffQKpmXQLBqvUNNjuhmpVKWBtrTdcCKrglFXiw0cKGHKxIirjmiOlB_HYHg5UdosyE3_1Txct2U7-WBB6QXak1UgxCzgKYBDI8UPA0RlkUuHHP_Zg0fVXrXIInHO04MYxUeSps5qqyP6dJBu_v_BDn3zUq6LYFwJ_-xsU7zbrKYB4jaRlHPoCj_eDC-rSA2uQ4KXHBB8_aAqNFC9ukWxc26Ifz9dF968DLuL30bi-ZAa2oUh492Pw1bg89J7i4qTsOOfpQvGyDV7TGhKuUG3Hbumfr2w16S-_3EI2RIyd1nYsflE6ZmCkZQMG_lwDAFXaqfyGKEDouJuja4XH8r4fGWeGTrozIoniXT1HU",
  "e": "AQAB"
}

Previous representation

A SubjectPublicKeyInfo ASN.1 data structure with RSAPublicKey (and rsaEncryption for the algorithm) looks like the following. This encapsulated the public key from Example A above:

  0 290: SEQUENCE {
  4  13:   SEQUENCE {
  6   9:     OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
 17   0:     NULL
       :     }
 19 271:   BIT STRING, encapsulates {
 24 266:     SEQUENCE {
 28 257:       INTEGER
       :         00 B1 B5 FC D8 D4 D5 E8 8C A5 C4 28 7B 31 F5 78
       :         86 5C AF 6A 78 82 6A 3B 8F F7 B1 B2 3A A4 AF 4E
       :         6A 04 74 13 9F 94 5B D9 D3 A9 11 FF D0 FA 72 DB
       :         78 E4 59 3A 86 C9 1F 9D A8 36 18 6E BD 34 02 D5
       :         1F 6A 38 44 24 7A B5 08 8B 46 92 9C 31 1B 43 60
       :         4F ED 84 49 9F 06 F0 F3 9B F5 55 90 E2 18 7F 1B
       :         BE 22 9B A8 F4 9F D2 E5 70 CD 0E 37 33 C7 6B FE
       :         DE 80 E1 E7 E0 88 1E 45 38 EA 1B C5 78 2B E9 51
       :         2F 8B F1 32 52 6E 05 F4 92 35 64 FE 6E 1E 21 BF
       :         70 87 AD EB B6 60 FA 53 3F CA 06 D0 A8 E6 69 91
       :         E1 31 2D 70 B6 4A 61 DA 8C A7 7C 02 8C DF 93 96
       :         01 E2 CF FE 28 55 75 9B 1D 47 9F 08 47 BC AC 59
       :         D7 D6 24 27 A4 31 D4 E3 DF D2 69 74 28 B9 DD 63
       :         09 A7 B1 16 7D B9 9F E0 1A F1 FF 1B 73 95 66 FB
       :         94 9E 47 08 9D 1D AE 84 AE F1 21 4E F7 F5 77 3E
       :         86 A0 D3 E9 DA 24 6F 9B EC 09 D6 0C 70 58 91 18
       :         3D
289   3:       INTEGER 65537
       :       }
       :     }
       :   }

@b5
Copy link
Contributor

b5 commented Sep 29, 2021

If we can find a way to do more compact RSA key representations, I'm all for it. After doing a little homework, I think @clehner's PR merits real consideration.

@rvagg a few points to help clarify the origin of this conversation: As far as I can tell the only people who need this multicodec entry are all working on implementing the did:key spec, which makes heavy use of multiformats. The spec is still making it's way into the wild, and at least three implementers across Typescript, Rust, and Go are invovled in this conversation & willing to change our implementations to match, so I don't think it's too late to make a change like this.

I'm working on a go implementation of did:key, and have been using go-libp2p-crypto as a target for interop. It seems like libp2p & did:key should naturally inter-operate, as both do asymmetric key type normalization. I think libp2p may be in the "wrong" here, and @clehner's proposal would be smarter.

Doing some digging through git history, it seems this chosen RSA representation has been part of the IPFS & Libp2p stack since at least the year 2015: libp2p/go-libp2p-crypto@b9038a3#diff-b4d8ce31e2465acb394fd7738faba5981e07e516bd5e406fc808fdd00f1f388cR35

I'm not going to drag Juan into this conversation to clarify why this representation was chosen, but I'm sure there's a reason. But in this case a more compact representation of public keys that is also removing an unused layer of normalization (SubjectPublicKeyInfo) is the right call.

@expede I'd welcome your input here as well.

@expede
Copy link
Contributor

expede commented Sep 29, 2021

Awesome; thanks @clehner 🎉

@b5, @expede (and anyone else): are you already using the current rsa-x509-pub/0x1205, such that this would break your existing installations and credentials?

Nope! I have a WIP branch for this, but "luckily" keep getting pulled away, so no conflicts on my side! Further, our previous "just get it working, we'll use a placeholder prefix code for now" version was also a 2048-bit RSAPublicKey (but in base58 per did:key), so this PR actually makes my life easier with fewer changes to Fission's code.

I'm working on a go implementation of did:key, and have been using go-libp2p-crypto as a target for interop

Fission has implementations in TypeScript and Haskell. We have access to lots of key format support. No strong preference here, I just want it to interop and not be filled with long certificate header data 😛

@expede
Copy link
Contributor

expede commented Sep 29, 2021

Oh, to be explicit: I'm strongly in favour of this change 👍

@rvagg
Copy link
Member

rvagg commented Sep 29, 2021

I'm happy to defer to you three if you reach agreement that this is the right way to go. Since it was only added less than a month ago we should be pretty safe adjusting it.

I'm working on a go implementation of did:key, and have been using go-libp2p-crypto as a target for interop. It seems like libp2p & did:key should naturally inter-operate, as both do asymmetric key type normalization.

So is the intention here to use this to support both SubjectPublicKeyInfo and RSAPublicKey possibilities under this single name, or are we just pushing this to be the latter, as per the comment column in the change? Do we need to teach go-libp2p-crypto to understand both, or is this new work for did:key operating entirely separately from that code so it's simply a matter of choosing and moving forward?

@b5 do you want to give an explicit 👍 on this first? It seems like @clehner and @expede are good to go.

@b5
Copy link
Contributor

b5 commented Sep 29, 2021

yep explicit 👍 from me. I think @clehner's steering us all in the right direction.

So is the intention here to use this to support both SubjectPublicKeyInfo and RSAPublicKey possibilities under this single name, or are we just pushing this to be the latter, as per the comment column in the change?

I'm under the impression the intention here is to switch the multicodec to only support RSAPublicKey, and think that's the right move.

Do we need to teach go-libp2p-crypto to understand both, or is this new work for did:key operating entirely separately from that code so it's simply a matter of choosing and moving forward?

We don't need to teach go-libp2p-crypto to understand RSAPublicKey for did:key work to proceed, so we can choose & move forward.

With that said, the lessons learned here also apply to libp2p-crypto, and we should open a separate discussion on go-libp2p-core to talk about the unnecessary SubjectPublicKeyInfo wrapping when calling pubKey.Raw() on a RSA public key. This would be a breaking change, so less chance it'll be taken up there.

@clehner
Copy link
Contributor Author

clehner commented Sep 29, 2021

@b5 @expede
I'm glad we can agree on this!

Edit: thanks @b5 for the interesting backstory as well.

@rvagg

So is the intention here to use this to support both SubjectPublicKeyInfo and RSAPublicKey possibilities under this single name, or are we just pushing this to be the latter, as per the comment column in the change?

I'm under the impression the intention here is to switch the multicodec to only support RSAPublicKey, and think that's the right move.

Right.

I think SubjectPublicKeyInfo could be useful as a separate entry though. It is also a recognized key format in WebCrypto: spki.

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

Successfully merging this pull request may close these issues.

4 participants