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

Support key command #5

Open
przemoc opened this issue Jan 12, 2024 · 6 comments
Open

Support key command #5

przemoc opened this issue Jan 12, 2024 · 6 comments

Comments

@przemoc
Copy link

przemoc commented Jan 12, 2024

id command is already supported, but another useful one would be key.

key should be equivalent of what following command does on private key:
openssl rsa -in key.pem -pubout -outform DER | openssl base64 -A

If CRX/ZIP's manifest.json has a key field, then key command could be made to work also on such CRX/ZIP files and display their key then.

This key value is useful for developers to keep consistent ID:
https://developer.chrome.com/docs/extensions/reference/manifest/key


BTW thank you for creating the tool! This year I have to update my web browser extension, NavigUp, and migrate to Manifest V3 (known issues, checklist) to ensure its users won't be impacted by Manifest V2 support timeline, specifically:

June 2024: Chrome MV2 deprecation pre-stable rollout
June 2024 + 1-X months: Chrome MV2 deprecation stable rollout

At some point Chrome deprecated CRX2 format and introduced CRX3 - CRX₃ Design Doc. Beside relying on Chrome Web Store, I always self-hosted my extension too, so being able to create CRX3 easily will be super handy.


In the distant past I used crxmake, possibly https://github.com/Constellation/crxmake, but I have no notes to tell for sure. I refuse to accept need to use hundred megabyte browser binary to create crx file. If not for your tool, i.e. crx3, I would possibly had to write one for myself (most likely in C/C++). There are some JavaScript based solutions, but I'm not fan of JavaScript runtime environments like Node.js, and prefer more standalone solutions.

@mmadfox
Copy link
Owner

mmadfox commented Jun 22, 2024

Thank you very much for the great ideas. I added the pubkey command in the new release.

@mmadfox mmadfox closed this as completed Jun 22, 2024
@przemoc
Copy link
Author

przemoc commented Jun 22, 2024

Thank you for introducing pubkey command. Did you test it with CRX files out there?

I did a quick check on my extension (still not migrated to MV3, but in CRX3 format when obtained from webstore), confronting results with handy Chrome extension source viewer, openssl, and webstore. go-crx3 doesn't seem to provide proper results.

go-crx3

$ crx3 pubkey ~/Downloads/eigojmmlmgigbldiclbpibmjnlbdpiaa.crx
MIIBCgKCAQEAj/u/XDdjlDyw7gHEtaaasZ9GdG8WOKAyJzXd8HFrDtz2Jcuy7er7MtWvHgNDA0bwpznbI5YdZeV4UfCEsA4SrA5b3MnWTHwA1bgbiDM+L9rrqvcadcKuOlTeN48Q0ijmhHlNFbTzvT9W0zw/GKv8LgXAHggxtmHQ/Z9PP2QNF5O8rUHHSL4AJ6hNcEKSBVSmbbjeVm4gSXDuED5r0nwxvRtupDxGYp8IZpP5KlExqNu1nbkPc+igCTIB6XsqijagzxewUHCdovmkb2JNtskx/PMIEv+TvWIx2BzqGp71gSh/dV7SJ3rClvWd2xj8dtxG8FfAWDTIIi0qZXWn2QhizQIDAQAB
$ crx3 id ~/Downloads/eigojmmlmgigbldiclbpibmjnlbdpiaa.crx
eigojmmlmgigbldiclbpibmjnlbdpiaa

Extension page > Chrome extension source viewer > View source > Dev Console:

Public key (paste into manifest.json to preserve extension ID)
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDR8RyDbBAaZaEsh4VTye63j6QDOGP1YMSCJ+2KyJXH8IHneddHl2mUKD27FrNNUm7N6NnzRSFmVRolvgph4CByu3D7mHdDekNk8cj0ilsfF+GlUllGPMCPzalp+Zitufq81Cg4oModC3SvPUT1gQIQ9NGGkjlOrBu9J6gs/syPRQIDAQAB",
Calculated extension ID: eigojmmlmgigbldiclbpibmjnlbdpiaa

openssl

$ openssl rsa -in navigup.pem -inform PEM -pubout -outform DER | openssl base64 -A
writing RSA key
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDR8RyDbBAaZaEsh4VTye63j6QDOGP1YMSCJ+2KyJXH8IHneddHl2mUKD27FrNNUm7N6NnzRSFmVRolvgph4CByu3D7mHdDekNk8cj0ilsfF+GlUllGPMCPzalp+Zitufq81Cg4oModC3SvPUT1gQIQ9NGGkjlOrBu9J6gs/syPRQIDAQAB

Chrome Web Store > Developer Dashboard > Extension > Build > Package > View public key

image

Short analysis

I noticed that output coming from go-crx3 is longer, so I did another quick check, by decoding base64 public keys, showing their info, and calculating extension ID from them.

$ echo 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDR8RyDbBAaZaEsh4VTye63j6QDOGP1YMSCJ+2KyJXH8IHneddHl2mUKD27FrNNUm7N6NnzRSFmVRolvgph4CByu3D7mHdDekNk8cj0ilsfF+GlUllGPMCPzalp+Zitufq81Cg4oModC3SvPUT1gQIQ9NGGkjlOrBu9J6gs/syPRQIDAQAB' | openssl base64 -d >pubkey1.der
$ echo 'MIIBCgKCAQEAj/u/XDdjlDyw7gHEtaaasZ9GdG8WOKAyJzXd8HFrDtz2Jcuy7er7MtWvHgNDA0bwpznbI5YdZeV4UfCEsA4SrA5b3MnWTHwA1bgbiDM+L9rrqvcadcKuOlTeN48Q0ijmhHlNFbTzvT9W0zw/GKv8LgXAHggxtmHQ/Z9PP2QNF5O8rUHHSL4AJ6hNcEKSBVSmbbjeVm4gSXDuED5r0nwxvRtupDxGYp8IZpP5KlExqNu1nbkPc+igCTIB6XsqijagzxewUHCdovmkb2JNtskx/PMIEv+TvWIx2BzqGp71gSh/dV7SJ3rClvWd2xj8dtxG8FfAWDTIIi0qZXWn2QhizQIDAQAB' | openssl base64 -d >pubkey2.der
$ openssl rsa -in pubkey1.der -inform DER -pubin -text
Public-Key: (1024 bit)
Modulus:
    00:d1:f1:1c:83:6c:10:1a:65:a1:2c:87:85:53:c9:
    ee:b7:8f:a4:03:38:63:f5:60:c4:82:27:ed:8a:c8:
    95:c7:f0:81:e7:79:d7:47:97:69:94:28:3d:bb:16:
    b3:4d:52:6e:cd:e8:d9:f3:45:21:66:55:1a:25:be:
    0a:61:e0:20:72:bb:70:fb:98:77:43:7a:43:64:f1:
    c8:f4:8a:5b:1f:17:e1:a5:52:59:46:3c:c0:8f:cd:
    a9:69:f9:98:ad:b9:fa:bc:d4:28:38:a0:ca:1d:0b:
    74:af:3d:44:f5:81:02:10:f4:d1:86:92:39:4e:ac:
    1b:bd:27:a8:2c:fe:cc:8f:45
Exponent: 65537 (0x10001)
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDR8RyDbBAaZaEsh4VTye63j6QD
OGP1YMSCJ+2KyJXH8IHneddHl2mUKD27FrNNUm7N6NnzRSFmVRolvgph4CByu3D7
mHdDekNk8cj0ilsfF+GlUllGPMCPzalp+Zitufq81Cg4oModC3SvPUT1gQIQ9NGG
kjlOrBu9J6gs/syPRQIDAQAB
-----END PUBLIC KEY-----
$ openssl rsa -in pubkey2.der -inform DER -pubin -text
Public-Key: (2048 bit)
Modulus:
    00:8f:fb:bf:5c:37:63:94:3c:b0:ee:01:c4:b5:a6:
    9a:b1:9f:46:74:6f:16:38:a0:32:27:35:dd:f0:71:
    6b:0e:dc:f6:25:cb:b2:ed:ea:fb:32:d5:af:1e:03:
    43:03:46:f0:a7:39:db:23:96:1d:65:e5:78:51:f0:
    84:b0:0e:12:ac:0e:5b:dc:c9:d6:4c:7c:00:d5:b8:
    1b:88:33:3e:2f:da:eb:aa:f7:1a:75:c2:ae:3a:54:
    de:37:8f:10:d2:28:e6:84:79:4d:15:b4:f3:bd:3f:
    56:d3:3c:3f:18:ab:fc:2e:05:c0:1e:08:31:b6:61:
    d0:fd:9f:4f:3f:64:0d:17:93:bc:ad:41:c7:48:be:
    00:27:a8:4d:70:42:92:05:54:a6:6d:b8:de:56:6e:
    20:49:70:ee:10:3e:6b:d2:7c:31:bd:1b:6e:a4:3c:
    46:62:9f:08:66:93:f9:2a:51:31:a8:db:b5:9d:b9:
    0f:73:e8:a0:09:32:01:e9:7b:2a:8a:36:a0:cf:17:
    b0:50:70:9d:a2:f9:a4:6f:62:4d:b6:c9:31:fc:f3:
    08:12:ff:93:bd:62:31:d8:1c:ea:1a:9e:f5:81:28:
    7f:75:5e:d2:27:7a:c2:96:f5:9d:db:18:fc:76:dc:
    46:f0:57:c0:58:34:c8:22:2d:2a:65:75:a7:d9:08:
    62:cd
Exponent: 65537 (0x10001)
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj/u/XDdjlDyw7gHEtaaa
sZ9GdG8WOKAyJzXd8HFrDtz2Jcuy7er7MtWvHgNDA0bwpznbI5YdZeV4UfCEsA4S
rA5b3MnWTHwA1bgbiDM+L9rrqvcadcKuOlTeN48Q0ijmhHlNFbTzvT9W0zw/GKv8
LgXAHggxtmHQ/Z9PP2QNF5O8rUHHSL4AJ6hNcEKSBVSmbbjeVm4gSXDuED5r0nwx
vRtupDxGYp8IZpP5KlExqNu1nbkPc+igCTIB6XsqijagzxewUHCdovmkb2JNtskx
/PMIEv+TvWIx2BzqGp71gSh/dV7SJ3rClvWd2xj8dtxG8FfAWDTIIi0qZXWn2Qhi
zQIDAQAB
-----END PUBLIC KEY-----
$ cat pubkey1.der | sha256sum | head -c32 | tr 0-9a-f a-p
eigojmmlmgigbldiclbpibmjnlbdpiaa
$ cat pubkey2.der | sha256sum | head -c32 | tr 0-9a-f a-p
ndbbbokdeocpkaiembjedmlfajdkoegn

I haven't analyzed your code, but above results at least show that go-crx3 assumes somewhere RSA >= 2K, which can not always be true for extensions added to webstore long time ago (e.g. my extension was created ~15y ago IIRC), i.e. before longer keys were strictly recommended / enforced.

CRX Viewer also uses RSA 1K, so you can test on it too if you want.


But it looks it's not only matter of key size.
I tried another extension, which uses RSA 2K, and for it pubkey also didn't return proper value.


EDIT: You can look at ASN.1 dumps (e.g. using ASN.1 JavaScript decoder as openssl asn1parse is limited) of pubkeys, even from above analysis, to better see some discrepancies (putting key size matter aside):

SubjectPublicKeyInfo SEQUENCE @0+159 (constructed): (2 elem)
  algorithm AlgorithmIdentifier SEQUENCE @3+13 (constructed): (2 elem)
    algorithm OBJECT_IDENTIFIER @5+9: 1.2.840.113549.1.1.1|rsaEncryption|PKCS #1
    parameters ANY NULL @16+0
  subjectPublicKey BIT_STRING @18+141 (encapsulates): (1120 bit)|...
    SEQUENCE @22+137 (constructed): (2 elem)
      INTEGER @25+129: (1024 bit)|...
      INTEGER @157+3: 65537
  • pubkey2.der - unexpected format provided by go-crx3 v1.5.0
RSAPrivateKey SEQUENCE @0+266 (constructed): (2 elem)
  version Version INTEGER @4+257: (2048 bit)|...
  modulus INTEGER @265+3: 65537

@mmadfox
Copy link
Owner

mmadfox commented Jun 25, 2024

Thank you for the detailed feedback! I will take it into account. I admit I skimmed through the specification and apparently misunderstood the task.

@mmadfox mmadfox reopened this Jun 25, 2024
mmadfox added a commit that referenced this issue Jun 26, 2024
* fix(pubkey, id): fix generate pubkey and extension id, #5

* chore(commands): some improvements
@mmadfox
Copy link
Owner

mmadfox commented Jun 26, 2024

@przemoc If possible, please check the latest release v1.5.1, where I fixed the retrieval of the ID from the public key and corrected the pubkey command. I compared (tested) the public keys and ID generation with Chrome tools and OpenSSL. Once again, thank you for the detailed description of the problem. If the issue is not resolved, please let me know.

@przemoc
Copy link
Author

przemoc commented Jun 29, 2024

@mmadfox Thanks for working on this. I cannot afford right now to do a more thorough check, but I just did two quick checks, firstly on my extension, secondly on another extension. We're not there yet. :)


$ ( crx3 pubkey ~/Downloads/eigojmmlmgigbldiclbpibmjnlbdpiaa.crx; echo ) | openssl base64 -d >pubkey3.der
$ openssl asn1parse -in pubkey3.der -inform DER -i
    0:d=0  hl=4 l= 290 cons: SEQUENCE
    4:d=1  hl=2 l=  13 cons:  SEQUENCE
    6:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
   17:d=2  hl=2 l=   0 prim:   NULL
   19:d=1  hl=4 l= 271 prim:  BIT STRING

So it looks like it follows SubjectPublicKeyInfo format, but subjectPublicKey is still somehow becoming 2K.

  • pubkey3.der - unexpected key size provided by go-crx3 v1.5.1

Which means that the first problem I brought up in my previous comment remains true:

I haven't analyzed your code, but above results at least show that go-crx3 assumes somewhere RSA >= 2K, which can not always be true for extensions added to webstore long time ago (e.g. my extension was created ~15y ago IIRC), i.e. before longer keys were strictly recommended / enforced.


It seems there is yet another issue. Pubkey seemingly returns same (garbage?) stuff now.

$ ( crx3 pubkey ~/Downloads/beakmhbijpdhipnjhnclmhgjlddhidpe.crx; echo ) | openssl base64 -d >linkding3.der
$ cat linkding3.der | sha256sum | head -c32 | tr 0-9a-f a-p
lfoeajgcchlidpicbabpmckkejpckcfb
$ cat pubkey3.der | sha256sum | head -c32 | tr 0-9a-f a-p
lfoeajgcchlidpicbabpmckkejpckcfb

@mmadfox
Copy link
Owner

mmadfox commented Jul 8, 2024

Thank you for the detailed report on the issue. I will fix the error soon. Yes, I missed something in the implementation…

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