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

时间:2014-02-22 07:32:58

标签: node.js encryption encoding rsa

我正在尝试使用ursa库在我当前的nodejs项目中使用RSA进行加密和解密逻辑。我真的无法在任何地方找到帮助,所以我希望有人可以提供帮助。

每当我运行此代码时,我都会遇到与填充相关的以下解码错误(仅当解密时。加密不会中断虽然我不确定它是否正确):

“错误:0407A079:rsa例程:RSA_padding_check_PKCS1_OAEP:oaep decode error”

我尝试将填充更改为ursa.RSA_PKCS1_PADDING,而不是使用默认的ursa.RSA_PKCS1_OAEP_PADDING,但ID没有帮助。我尝试使用一个填充进行加密,并使用另一个填充进行解密,但它无法正常工作。我相信我尝试了所有的编码组合(二进制,utf8和base64)用于缓冲区和加密/解密方法,但它不能正常工作。

以下是我正在尝试运行的整个测试代码:

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;
}

我可能在这里做了一些非常愚蠢的事情,但老实说,此时我找不到问题。谢谢=)

2 个答案:

答案 0 :(得分:3)

其中一个问题是,如果你没有指定编码,那么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();
}

谢谢!如果有人想要做得更好,我们非常欢迎。

谢谢!

答案 1 :(得分:1)

我有类似的问题。在我的情况下,我在android中加密并使用ursa在节点中解密。在我的情况下,android没有使用任何填充,而ursa默认使用RSA_PKCS1_OAEP_PADDING。 所以我不得不使用RSA_NO_PADDING而且它有效!