RSA Encryption and Decryption successed in JS, but Decryption fails in C#

前端 未结 1 905
春和景丽
春和景丽 2020-12-20 05:50

For security, I encrypted some data, such as username, passwords, and emails in the browser by jsencrypt which is a A Javascript library to perform OpenSSL RSA Encryption, D

相关标签:
1条回答
  • 2020-12-20 06:42

    Your javascript encryption is producing results that do not conform to the RSAES-PKCS1-V1_5-ENCRYPT specification.

    Your modulus is a 1024-bit number (128 bytes). Therefore the output of all encrypted messages will be 128 bytes.

    https://tools.ietf.org/html/rfc3447#section-7.2.1:

    c. Convert the ciphertext representative c to a ciphertext C of length k octets (see Section 4.1):

    C = I2OSP (c, k).
    

    ("of length k", not "of length up to k").

    The third values that you've presented all end with ==, which means that the number of bytes mod 3 is 1. But 128 mod 3 is 2. Therefore the output here is not a legal output of I2OSP(c, 128).

    The javascript library you are using is leaving off the leading zeros. So to fix this in .NET you would do

    public byte[] Decrypt(byte[] bytes)
    {
        using (var rsa = new RSACryptoServiceProvider())
        {
            rsa.ImportParameters(PrivateParameters);
    
            // Correct the error in the JS encryptor.
            if (bytes.Length < rsa.KeySize / 8)
            {
                byte[] tmp = new byte[rsa.KeySize / 8];
                Buffer.BlockCopy(bytes, 0, tmp, tmp.Length - bytes.Length, bytes.Length);
                bytes = tmp;
            }
    
            return rsa.Decrypt(bytes, RSAEncryptionPadding.Pkcs1);
        }
    }
    

    Note that I didn't say + 1, because given the observed behavior of the javascript library, if the encryption produced a value which should have started with 00 00 it will leave off both of them.

    And filing a bug with the library owner seems good :).

    0 讨论(0)
提交回复
热议问题