使用带有节点的ursa加密和解密字符串会产生解码错误

时间:2021-10-21 18:24:42

I am trying to use ursa library to make encryption and decryption logics with RSA in my current nodejs project. I really couldn't find help on this anywhere so I'm hoping someone can help.

我正在尝试在我当前的nodejs项目中使用ursa库对RSA进行加密和解密。我真的在任何地方都找不到帮助,所以我希望有人能帮忙。

Whenever I run this code I get the following decoding error related to the padding (only when DECRYPTING. Encrypting does not break although I'm not sure it is correct):

每当我运行这段代码时,我都会得到以下与填充相关的解码错误(只有在解密时才会出现)。加密不会中断,虽然我不确定它是正确的):

"error:0407A079:rsa routines:RSA_padding_check_PKCS1_OAEP:oaep decoding error"

“错误:0407 a079:rsa例程:RSA_padding_check_PKCS1_OAEP:oaep解码错误”

I tried changing the padding to ursa.RSA_PKCS1_PADDING instead of using the default ursa.RSA_PKCS1_OAEP_PADDING but id didn't help. I tried encrypting with one padding and decrypting with another one as well and it didn't work. I believed I tried all combinations of encoding (binary, utf8 and base64) for the buffers and encryption/decryption methods but it didn't work as well.

我试着把填充物改成ursa。使用RSA_PKCS1_PADDING,而不是使用默认的ursa。RSA_PKCS1_OAEP_PADDING但id没有帮助。我试着用一个填充进行加密,用另一个填充进行解密,但没有成功。我相信我尝试了所有的编码组合(二进制、utf8和base64)用于缓冲区和加密/解密方法,但它并没有同样有效。

Here is the whole of the test code I'm trying to run:

下面是我要运行的全部测试代码:

var ursa = require("ursa");

var privateKey = ursa.generatePrivateKey(2048, 65537);

//var pub = privateKey.toPublicPem('base64');
//var priv = privateKey.toPrivatePem('base64');

var clearText = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."

var encrypted = encrypt(clearText, 256);
var decrypted = decrypt(encrypted, 256);


function encrypt(text, keySizeBytes){
    var buffer = new Buffer(text);
    var maxBufferSize = keySizeBytes - 42;
    var bytesCopied = 0;
    var finalString = "";

    //loops through all data buffer encrypting piece by piece
    while(bytesCopied < buffer.length){
        //calculates next maximun length for temporary buffer and creates it
        var amountToCopy = Math.min(maxBufferSize, buffer.length - bytesCopied);
        var tempBuffer = new Buffer(amountToCopy);

        //copies next chunk of data to the temporary buffer
        var nextEnd = bytesCopied + amountToCopy;
        buffer.copy(tempBuffer, 0, bytesCopied, nextEnd);

        //encrypts current chunk and concatenates with encrypted parts
        finalString += privateKey.encrypt(tempBuffer);

        bytesCopied += amountToCopy;
    }

    return finalString;
}

function decrypt(text, keySizeBytes){
    var buffer = new Buffer(text);
    var maxBufferSize = keySizeBytes - 1;
    var bytesCopied = 0;
    var finalString = "";

    //loops through all data buffer encrypting piece by piece
    while(bytesCopied < buffer.length){
        //calculates next maximun length for temporary buffer and creates it
        var amountToCopy = Math.min(maxBufferSize, buffer.length - bytesCopied);
        var tempBuffer = new Buffer(amountToCopy);

        //copies next chunk of data to the temporary buffer
        var nextEnd = bytesCopied + amountToCopy;
        buffer.copy(tempBuffer, 0, bytesCopied, nextEnd);

        //drecrypts current chunk and concatenates with decrypted parts
        finalString += privateKey.decrypt(tempBuffer);

        bytesCopied += amountToCopy;
    }

    return finalString;
}

I may be doing something really stupid here but honestly at this point I can't find the problem. Thanks =)

我可能在做一些很愚蠢的事情,但老实说,我找不到问题所在。谢谢=)

2 个解决方案

#1


3  

One of the problems was that the ursa encrypt and decrypt methods return a Buffer if you don't specify the encoding so my concatenation did weird stuff. Besides I realised that any string encrypted with a key of N bytes will have N bytes. Taking those into account I improved the code and here's my final suggestion for anyone needing to encrypt and decrypt strings of any size using ursa.

其中一个问题是,如果不指定编码,ursa加密和解密方法会返回一个缓冲区,所以我的连接做了一些奇怪的事情。此外,我还意识到任何用N字节密钥加密的字符串都有N个字节。考虑到这些,我对代码进行了改进,下面是我对任何需要使用ursa对任意大小的字符串进行加密和解密的人的最后建议。

var ursa = require("ursa");

var clearText = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
var bigText = "";
for(var i = 0; i < 100; i++){
    bigText += i +" " + clearText + "\n"; 
}

var keySizeBits = 1024;
var keyPair = ursa.generatePrivateKey(keySizeBits, 65537);

var encrypted = encrypt(bigText, keySizeBits/8);
console.log(encrypted);

var decrypted = decrypt(encrypted, keySizeBits/8);
console.log(decrypted);

function encrypt(clearText, keySizeBytes){
    var buffer = new Buffer(clearText);
    var maxBufferSize = keySizeBytes - 42; //according to ursa documentation
    var bytesDecrypted = 0;
    var encryptedBuffersList = [];

    //loops through all data buffer encrypting piece by piece
    while(bytesDecrypted < buffer.length){
        //calculates next maximun length for temporary buffer and creates it
        var amountToCopy = Math.min(maxBufferSize, buffer.length - bytesDecrypted);
        var tempBuffer = new Buffer(amountToCopy);

        //copies next chunk of data to the temporary buffer
        buffer.copy(tempBuffer, 0, bytesDecrypted, bytesDecrypted + amountToCopy);

        //encrypts and stores current chunk
        var encryptedBuffer = keyPair.encrypt(tempBuffer);
        encryptedBuffersList.push(encryptedBuffer);

        bytesDecrypted += amountToCopy;
    }

    //concatenates all encrypted buffers and returns the corresponding String
    return Buffer.concat(encryptedBuffersList).toString('base64');
}

function decrypt(encryptedString, keySizeBytes){

    var encryptedBuffer = new Buffer(encryptedString, 'base64');
    var decryptedBuffers = [];

    //if the clear text was encrypted with a key of size N, the encrypted 
    //result is a string formed by the concatenation of strings of N bytes long, 
    //so we can find out how many substrings there are by diving the final result
    //size per N
    var totalBuffers = encryptedBuffer.length / keySizeBytes;

    //decrypts each buffer and stores result buffer in an array
    for(var i = 0 ; i < totalBuffers; i++){
        //copies next buffer chunk to be decrypted in a temp buffer
        var tempBuffer = new Buffer(keySizeBytes);
        encryptedBuffer.copy(tempBuffer, 0, i*keySizeBytes, (i+1)*keySizeBytes);
        //decrypts and stores current chunk
        var decryptedBuffer = keyPair.decrypt(tempBuffer);
        decryptedBuffers.push(decryptedBuffer);
    }

    //concatenates all decrypted buffers and returns the corresponding String
    return Buffer.concat(decryptedBuffers).toString();
}

Thanks anyways! If anyone has any thoughts to make this better they are very welcome.

谢谢你不管怎样!如果有人有更好的想法,他们是非常受欢迎的。

Thanks!

谢谢!

#2


1  

I had a similar issue. In my case, I was encrypting in android and decrypting in node using ursa. In my case, android was not using any padding whereas ursa by default uses RSA_PKCS1_OAEP_PADDING. So I had to use RSA_NO_PADDING and it worked!

我也有类似的问题。在我的例子中,我在android中加密和使用ursa在节点中解密。在我的例子中,android不使用任何填充,而ursa默认使用RSA_PKCS1_OAEP_PADDING。所以我必须使用RSA_NO_PADDING属性。

#1


3  

One of the problems was that the ursa encrypt and decrypt methods return a Buffer if you don't specify the encoding so my concatenation did weird stuff. Besides I realised that any string encrypted with a key of N bytes will have N bytes. Taking those into account I improved the code and here's my final suggestion for anyone needing to encrypt and decrypt strings of any size using ursa.

其中一个问题是,如果不指定编码,ursa加密和解密方法会返回一个缓冲区,所以我的连接做了一些奇怪的事情。此外,我还意识到任何用N字节密钥加密的字符串都有N个字节。考虑到这些,我对代码进行了改进,下面是我对任何需要使用ursa对任意大小的字符串进行加密和解密的人的最后建议。

var ursa = require("ursa");

var clearText = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
var bigText = "";
for(var i = 0; i < 100; i++){
    bigText += i +" " + clearText + "\n"; 
}

var keySizeBits = 1024;
var keyPair = ursa.generatePrivateKey(keySizeBits, 65537);

var encrypted = encrypt(bigText, keySizeBits/8);
console.log(encrypted);

var decrypted = decrypt(encrypted, keySizeBits/8);
console.log(decrypted);

function encrypt(clearText, keySizeBytes){
    var buffer = new Buffer(clearText);
    var maxBufferSize = keySizeBytes - 42; //according to ursa documentation
    var bytesDecrypted = 0;
    var encryptedBuffersList = [];

    //loops through all data buffer encrypting piece by piece
    while(bytesDecrypted < buffer.length){
        //calculates next maximun length for temporary buffer and creates it
        var amountToCopy = Math.min(maxBufferSize, buffer.length - bytesDecrypted);
        var tempBuffer = new Buffer(amountToCopy);

        //copies next chunk of data to the temporary buffer
        buffer.copy(tempBuffer, 0, bytesDecrypted, bytesDecrypted + amountToCopy);

        //encrypts and stores current chunk
        var encryptedBuffer = keyPair.encrypt(tempBuffer);
        encryptedBuffersList.push(encryptedBuffer);

        bytesDecrypted += amountToCopy;
    }

    //concatenates all encrypted buffers and returns the corresponding String
    return Buffer.concat(encryptedBuffersList).toString('base64');
}

function decrypt(encryptedString, keySizeBytes){

    var encryptedBuffer = new Buffer(encryptedString, 'base64');
    var decryptedBuffers = [];

    //if the clear text was encrypted with a key of size N, the encrypted 
    //result is a string formed by the concatenation of strings of N bytes long, 
    //so we can find out how many substrings there are by diving the final result
    //size per N
    var totalBuffers = encryptedBuffer.length / keySizeBytes;

    //decrypts each buffer and stores result buffer in an array
    for(var i = 0 ; i < totalBuffers; i++){
        //copies next buffer chunk to be decrypted in a temp buffer
        var tempBuffer = new Buffer(keySizeBytes);
        encryptedBuffer.copy(tempBuffer, 0, i*keySizeBytes, (i+1)*keySizeBytes);
        //decrypts and stores current chunk
        var decryptedBuffer = keyPair.decrypt(tempBuffer);
        decryptedBuffers.push(decryptedBuffer);
    }

    //concatenates all decrypted buffers and returns the corresponding String
    return Buffer.concat(decryptedBuffers).toString();
}

Thanks anyways! If anyone has any thoughts to make this better they are very welcome.

谢谢你不管怎样!如果有人有更好的想法,他们是非常受欢迎的。

Thanks!

谢谢!

#2


1  

I had a similar issue. In my case, I was encrypting in android and decrypting in node using ursa. In my case, android was not using any padding whereas ursa by default uses RSA_PKCS1_OAEP_PADDING. So I had to use RSA_NO_PADDING and it worked!

我也有类似的问题。在我的例子中,我在android中加密和使用ursa在节点中解密。在我的例子中,android不使用任何填充,而ursa默认使用RSA_PKCS1_OAEP_PADDING。所以我必须使用RSA_NO_PADDING属性。