简体   繁体   English

从节点js中存储的文件中读取公钥和私钥

[英]Reading public and private key from stored files in node js

I wanted to encrypt and decrypt a message in node using public and private keys stored in my system.我想使用存储在我的系统中的公钥和私钥来加密和解密节点中的消息。 I was using the following java code to read the file and use the keys.我正在使用以下 java 代码来读取文件并使用密钥。

Java Code: Java代码:

byte[]  keyBytes = Files.readAllBytes(new File(publicKeyFileName).toPath());
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
publicKey=kf.generatePublic(spec);

I am able to use the above java method without any issues to read the public key from file.我可以毫无问题地使用上述 java 方法从文件中读取公钥。 However, I want to achieve similar functionality in node.但是,我想在 node.js 中实现类似的功能。 I have tried using crypto for achieving the same but it gives me error while passing the key to publicEncrypt method.我曾尝试使用加密来实现相同的目的,但是在将密钥传递给publicEncrypt方法时它给了我错误。

Node:节点:

var encryptStringWithRsaPublicKey = function(toEncrypt, relativeOrAbsolutePathToPublicKey) {
    var absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey);
    var publicKey = fs.read(absolutepath, "utf-8");
    console.log(publicKey);
    var buffer = Buffer.from(toEncrypt);
    var encrypted = crypto.publicEncrypt(publicKey, buffer);
    return encrypted.toString("base64");
};

Error错误

internal/crypto/cipher.js:43
    return method(toBuf(key), buffer, padding, passphrase);
           ^

Error: error:0906D06C:PEM routines:PEM_read_bio:no start line

Please help.请帮忙。 Thanks谢谢

There's potentially a few issues with your code or the encryption key you're using:您的代码或您使用的加密密钥可能存在一些问题:

  1. You're using fs.read incorrectly as Node is asynchronous and it needs a callback function to properly read the file.您使用fs.read不正确,因为 Node 是异步的,它需要一个回调函数来正确读取文件。
  2. The encryption key you're using is formatted incorrectly for crypto.publicEncrypt .您使用的加密密钥格式不正确,用于crypto.publicEncrypt You must have the proper RSA headers.您必须具有正确的 RSA 标头。

I modified your code to use fs.readFile properly instead in the standard Node callback form, and here's an example encryption key in the correct RSA format to use:我修改了您的代码以在标准节点回调表单中正确使用fs.readFile ,这里有一个使用正确 RSA 格式的示例加密密钥:

var path = require('path');
var crypto = require('crypto');
var fs = require('fs');

var encryptStringWithRsaPublicKey = function(toEncrypt, relativeOrAbsolutePathToPublicKey, callback) {
    var absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey);
    fs.readFile(absolutePath, 'utf-8', (err, publicKey) => {
        // The value of `publicKey` is in the callback, not the return value
        console.log(publicKey);
        var buffer = Buffer.from(toEncrypt);
        var encrypted = crypto.publicEncrypt(publicKey, buffer);
        if (err) {
            callback(err);
        } else {
            callback(null, encrypted.toString("base64"));
        }
    });
};

encryptStringWithRsaPublicKey('hello world', 'test.pub', (err, encrypted) => {
    // If you're using a callback in a function,
    // the original function must have a callback as well
    console.log(encrypted);
}); 

Example encryption key at test.pub (must have the RSA headers as shown below): test.pub示例加密密钥(必须具有如下所示的 RSA 标头):

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA+xGZ/wcz9ugFpP07Nspo6U17l0YhFiFpxxU4pTk3Lifz9R3zsIsu
ERwta7+fWIfxOo208ett/jhskiVodSEt3QBGh4XBipyWopKwZ93HHaDVZAALi/2A
+xTBtWdEo7XGUujKDvC2/aZKukfjpOiUI8AhLAfjmlcD/UZ1QPh0mHsglRNCmpCw
mwSXA9VNmhz+PiB+Dml4WWnKW/VHo2ujTXxq7+efMU4H2fny3Se3KYOsFPFGZ1TN
QSYlFuShWrHPtiLmUdPoP6CV2mML1tk+l7DIIqXrQhLUKDACeM5roMx0kLhUWB8P
+0uj1CNlNN4JRZlC7xFfqiMbFRU9Z4N6YwIDAQAB
-----END RSA PUBLIC KEY-----

As of 2020, there are also other ways of making the code cleaner, such as with using the Promises version of the fs module and async / await, though I wanted to keep this answer as simple as possible for now.到 2020 年,还有其他方法可以使代码更简洁,例如使用 Promises 版本的fs模块和 async / await,但我现在想使这个答案尽可能简单。

Your problem is located in the file format you are actually using with Java.您的问题在于您在 Java 中实际使用的文件格式。 You probably save the private and the public in encoded ("byte array") to a file and rebuild the keys eg with X509EncodedKeySpec.您可能将编码(“字节数组”)中的私有和公共保存到一个文件中并重建密钥,例如使用 X509EncodedKeySpec。

This format is not compatible to Node.JS and you have 3 ways to solve it:这种格式与 Node.JS 不兼容,您有 3 种方法来解决它:

a) you write the keys in Java with re neccessary format for usage in Node.JS a) 您用 Java 编写密钥,并使用必要的格式在 Node.JS 中使用

b) you write a converter in Node.JS to get the correct format b) 您在 Node.JS 中编写了一个转换器以获得正确的格式

c) you convert the files with a tool like OPENSSL. c) 您使用 OPENSSL 之类的工具转换文件。

Here I show you the "c-way" as you are handling just one keypair and probably don't need a programatically solution.在这里,我向您展示了“c-way”,因为您只处理一个密钥对,并且可能不需要编程解决方案。

Let's say you have two files with the private key ("rsa_privatekey_2048.der") and the public key ("rsa_publickey_2048.der").假设您有两个文件,分别带有私钥(“rsa_privatekey_2048.der”)和公钥(“rsa_publickey_2048.der”)。

In OPENSSL you are using the command line with在 OPENSSL 中,您正在使用命令行

openssl rsa -inform der -in rsa_privatekey_2048.der -outform pem -out rsa_privatekey_2048.pem
openssl rsa -inform der -pubin -in rsa_publickey_2048.der -outform pem -RSAPublicKey_out -out rsa_publickey_2048.pem

to convert the files to their PEM-encoded formats.将文件转换为其 PEM 编码格式。

Below you can find the two sample files I created.您可以在下面找到我创建的两个示例文件。

rsa_privatekey_2048.pem: rsa_privatekey_2048.pem:

-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAmbeKgSAwVe0nZ84XlbDhMkUDjx1C0duA16MkzHTg1uh9SouO
KK0e3gPtTJ9LssaHlXSYhjpMDMWGO6ujd85XRosI2u9eSMNRYY25AQuBriSTVdi9
BHqWAuWuo6VuvTrkgWTL69vNWvLXTOkTiIyrgnhiavjNvm4UVy2AcO2Y3ER+dKgJ
pQAYlEP1jvuQuf6dfNdSBoN0DZbxZXYbQqoA9R/u0GZHCXY+r8A54RejG34pnnuH
koyROZz5H9LbKGOiaETryornQ1TRvB/p9tgIoCJFI71WsKsqeWQPG3Ymg/FoEWXN
Y0yopZEjpkZa3tU+hrOmAFIRg+/bedKfjYFi/QIDAQABAoIBAD3XZ3N3fbq0BExw
z3A7jv3oYfwrq3w+MOGQEvfmdaZANlfNOU4ICAkNz2QqGgw8bsOj+tDVl070EILl
FIjYjKgmu1NJRcdEPPNgTvOqq2th75xz6+dnYf6cZNwVbC3ZCaE86gVjkoRqek/I
3UDsRvvgbsfWfP+Fzc0c0zWbgQnsK6qivU1uzJX+5xsvgQlZboeZOO2lsdQMgfnu
iGlW1bVVM4Sy7AngqfiKMzihUnYEBIi0Y+mfxAPcBLUW8mrOvIOPPuNNUPxUtkBF
bDEzZ6loXCLLD8UBqXeDbCUPPFdTGcc7INhVgFdl2FL6rHB0+p6eUt8MI/XkZI2d
2AnkBUkCgYEA34cKLs2l5bPjyKybbj6ZG7RhDRsnPypEGU63DMV21twISqt7ZQNv
i3iTP+FYHM3ImECbNRIOZpyLuWLPmh5+5egQH13jRDempoxVSVcghbIserlCz2EU
nD2V6ZKuaDbn395O6Qe/PE/yKHLWbXwJrBBm+o7GGNm/Jd3KJib23PcCgYEAsAxB
esEsxxL8hqg/qf+ij7JJt492svpK/6QXhqeeP/FVOtYSgoNtSrXh9qahGpzMSF0m
FqwIgrOX0RkK3v6ofGVfIKObxOVyhwddS1Ru+SnjBFnTMKS57q0WNrIrBNM6Q0xE
Wd3tiljwmg8xF90U/BXu+m0v5XWKxSn7VLiCBqsCgYEAgl0xtSY/EP6fZJQ2ek+L
4DqNN6WUeCRgXxonbA1mR91AALyOVNVyIreJuYHlb7ccvJ9BZexH9dRrMQ3N4ibS
/6cecAzD1S9XxF6oBwQHdbH6ewC9VFFcQdsxKW5gxWrwRQJUp1fbUoOVyb1gDa5/
vZg7VvoZ0rh74Mu/cAzdgPUCgYEAiNANdwt29AKyUyefykpLGCczGL8aPP88l6z7
R38uAX1Ygg/pdJoUrnHo+FkIbHkcXMRfHFF3j7NoMWynwSLg50OUiPX80SiLN5qm
iytDzskZjsEL2gq6IF1NHRabTfWlmrVDjR9mQhTabq+NtIDwlPOqs9100nrlbFIy
6uU0z18CgYEAkDxQg5UjOzbYIighp/e0LkfKlwUE/cMtISUq1A6Yio9AKZYdBV8p
dd4osUW0gZvDflXlQaBIaNlOwl035lyEZtyuKmFh1oSmoir/TTMbIk0avSgKCLGg
fnhabaQRHl4RdXWcEsioRv3aZUsGkb46Y8xODyAUPRHBPhBsd71gnZ8=
-----END RSA PRIVATE KEY-----

rsa_publickey_2048.pem: rsa_publickey_2048.pem:

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAmbeKgSAwVe0nZ84XlbDhMkUDjx1C0duA16MkzHTg1uh9SouOKK0e
3gPtTJ9LssaHlXSYhjpMDMWGO6ujd85XRosI2u9eSMNRYY25AQuBriSTVdi9BHqW
AuWuo6VuvTrkgWTL69vNWvLXTOkTiIyrgnhiavjNvm4UVy2AcO2Y3ER+dKgJpQAY
lEP1jvuQuf6dfNdSBoN0DZbxZXYbQqoA9R/u0GZHCXY+r8A54RejG34pnnuHkoyR
OZz5H9LbKGOiaETryornQ1TRvB/p9tgIoCJFI71WsKsqeWQPG3Ymg/FoEWXNY0yo
pZEjpkZa3tU+hrOmAFIRg+/bedKfjYFi/QIDAQAB
-----END RSA PUBLIC KEY-----

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM