travist / jsencrypt

A zero-dependency Javascript library to perform OpenSSL RSA Encryption, Decryption, and Key Generation.
http://www.travistidwell.com/jsencrypt
Other
6.68k stars 2.01k forks source link

Front-end performed RSA signature on the HMAC using SHA256, but the length was incorrect, causing the server to fail to verify it. #293

Open stdzwei opened 1 year ago

stdzwei commented 1 year ago

My Code

rawGenerateEncryptData(rsa, obj, function sign(hmac) {
  let rsa = new JSEncrypt()
  rsa.setPrivateKey(privateKey)
  return rsa.sign(hmac, CryptoJS.SHA256, "sha256");
})

Where the error occurred

 RSAKey.prototype.sign = function (text, digestMethod, digestName) {
    // ....
    var h = c.toString(16);
    if ((h.length & 1) == 0) {
        return h;
    }
    else {
        return "0" + h;
   }
}

The cause of the problem: The digestName is SHA-256, but the length of h may not be 512. If you use the operator &, it will not append 0 to the start of the string when the length is 510, but SHA-256 requires 256. Additionally, 510 >> 1 is 255.

Fix it

if(digestName === 'sha256' && (h.length >> 1) != 256){
  const arr = []
  for (let i = 0; i < ((256 << 1) - h.length); i++) {
    arr.push('0')
  }
  return arr.join('') + h;
} else if ((h.length & 1) == 0) {
  return h;
} else {
  return "0" + h;
}
ChenHanHui commented 3 months ago

Yes, I had this problem too. It happened by accident.