-
-
Notifications
You must be signed in to change notification settings - Fork 643
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
Leniency in parsing block type byte and padding bytes for PKCS#1 v1.5 signature verification #478
Comments
Any plan to address the issue? It is listed as CVE-2021-30246 |
Hi, I'll fix this issue in a few days. Thanks. |
This issue was fixed in the latest release 10.2.0. Thanks. |
Security advisory for this issue was published: |
This was referenced May 11, 2022
This was referenced May 18, 2022
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Another finding besides the incompatibility issue reported here for PKCS#1 v1.5 signature verification, is the leniency in parsing the prefix of PKCS#1 structure.
Background. The prefix to the top ASN.1 structure of the PKCS1 v1.5 encoded message consists of leading byte (
0x00
), block type byte (0x01
for RSA signing scheme), padding bytes (0xFF...FF
), and the end of padding (0x00
). The length of padding bytes should also be at least 8 bytes and computed such that the final length of the PKCS#1 encoded message is equal to the length of public modolousN
(denoted by|| N ||
). Block type byte is there to indicate to which RSA scheme this encoded message is belonged. The end of padding also specifies where padding bytes actually ends. The leading byte (0x00
) also guarantees that the integer representative of the encoded message is not greater than or equal to the public modolousN
. By and large, the prefix bytes should satisfy the requirements in order for RSA PKS1 v1.5 signature scheme to be able to hold on to its security promises.Problem. However, jsrsasign v10.1.13 is lenient in checking such requirements and some other invalid signatures are mistakenly recognized to be valid. As will be shown below in the snippet taken from the source code, the issue arises because the implementation ignores the initial
0x00
bytes as they will disappear in octet strings to integer translation and more importantly the fact that an incorrect regex pattern matching is being used to peel off the prefix from the the top ASN.1 structure. This bug seems to be of similar type previously reported on RSA-PSS signature validation.More detailed root cause analysis. In line
248
@RSAKey.prototype.verify
function injsrsasign.js
file, the initial0x00
bytes will be ignored when octet strings are converted to integer (b = parseBigInt(j, 16)
) and converted back to octet strings after taking modular exponentiation to the power public exponent (i = this.doPublic(b)
andi.toString(16)
). The regex being used ini.toString(16).replace(/^1f+00/, "")
to remove the prefix only checks for the initial string1f+00
. So, it does not actually check for the padding bytes (0xFF....FF
) and can be bypassed by long initial zeros (examples are given).Implication: (Interoperability issue) As this might not be susceptible to an immediate signature forgery attack because without the ability to hide random bytes, the attack cost seems to be prohibitive. However, this can simply create an interoperability issue.
Reference notation and concrete values
N
: public modulus|N|
: length of public modulusd
: private exponente
: public exponentH
: hash functionm
: messageI
: to-be-singed RSA PKCS#1 v1.5 signature scheme input structureS
: signature value obtained byI^d mod N
Example#1: Padding bytes with length 1
I = 0x0001ff003031300d0609608648016503040201050004207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9
S = 0x3fa376d1e4f51e9ff32636fe4d5c1b22b9f3d2e5d017ea79168e8e297316c4ca980827ad333f983bf9628e212a21f5fe5f2bde47088ef6b002cef31f9ce395abd6400f2ddfc8c2d152174ff47bf9e396843033c752df8613054692ef0489fb59e3bd31e30ed18d83474c898236d4691b03d80c46c5fdbb1e8c5901c65748d0fc6857b64cd6baab722ac827d1d1e2cb1638afebe83547115747590eb83808e3dd99df942dc45461bb54efc5e52dc989af33c1518612571288de34542241b3ae98a3600499206be8c2fb56b14ca967712161666adabd8f79723d5b274c5cf8c84f5b2e158294662de15e897b298c9203829bc846eeccce9b424d6cf7a1d9fa284e
Example#2: All zero bytes as prefix
I = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003031300d0609608648016503040201050004207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9
S = 0xe5c9db5fb1f81cf431a568caeea54e3e7a3d54a2ae16929ecf52da9ea7018f18e7d3b2c3968a338d8b0cd0233c3073a25689da5310f52f2c14bf89c81ab2d8e2a0a5bef4403199aaa7a2bef6af6b33b15828f646358193c4ef8360c48e70f6e632b81432910b94b73854413fdb61f5377d88c5bb9848cd301b6e7609f90f4af94cbfae053fe7e9bcedd1c905d8a26f01133607d8f81efe993ad9daf78188ddbe6496dd7b6bea2cb3617708b96ccd9e0ca2398dd34d81567d2644f7a3ae4956a674e389aab9d8f1e732759209ddf17fd01cc347e6c74464c03e4d57be3052582f04c8553a6ebc6046742c659d7f542b4c72f8966dfde06036ad47d190dcddd03a
Example#3: It can start with some number of
0x00
bytes, and then0x1f
byte followed by some0xff
bytes ending with0x00
byte.I = 0x00001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d0609608648016503040201050004207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9
S = 0x472a5cb99114a3815d427b75b7e331192099bbf8e472995979395a53baa988a156b96c56bf9afa2c190103067a61e7caf99fb899f5023d9bf5eadb22ac90e2436c18ea7fac586eba9c5dee509b4e5f5d13d835dc139cb06a37b8caa1a4a66e1b8131987141139649b51ffdc48c8a28dfce9d8a6374136b959d8a916aaecc781829dd1d63147a4323807995b15c4c2542c1018fd990554ac978425c44c4575471222fdf218bd7378d696bf103a45fe05e53fd073290287d2fd9565b04b3467e2b3da4ee2a73211bf594ecf11b06ba5efeb61012ba1699624e2dbdffd060de930fff76019262714dd412946d7678f77720181c3f7316261d22c175c746e660fa4c
The text was updated successfully, but these errors were encountered: