簡體   English   中英

從節點js中存儲的文件中讀取公鑰和私鑰

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

我想使用存儲在我的系統中的公鑰和私鑰來加密和解密節點中的消息。 我正在使用以下 java 代碼來讀取文件並使用密鑰。

Java代碼:

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

我可以毫無問題地使用上述 java 方法從文件中讀取公鑰。 但是,我想在 node.js 中實現類似的功能。 我曾嘗試使用加密來實現相同的目的,但是在將密鑰傳遞給publicEncrypt方法時它給了我錯誤。

節點:

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

錯誤

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

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

請幫忙。 謝謝

您的代碼或您使用的加密密鑰可能存在一些問題:

  1. 您使用fs.read不正確,因為 Node 是異步的,它需要一個回調函數來正確讀取文件。
  2. 您使用的加密密鑰格式不正確,用於crypto.publicEncrypt 您必須具有正確的 RSA 標頭。

我修改了您的代碼以在標准節點回調表單中正確使用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);
}); 

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

到 2020 年,還有其他方法可以使代碼更簡潔,例如使用 Promises 版本的fs模塊和 async / await,但我現在想使這個答案盡可能簡單。

您的問題在於您在 Java 中實際使用的文件格式。 您可能將編碼(“字節數組”)中的私有和公共保存到一個文件中並重建密鑰,例如使用 X509EncodedKeySpec。

這種格式與 Node.JS 不兼容,您有 3 種方法來解決它:

a) 您用 Java 編寫密鑰,並使用必要的格式在 Node.JS 中使用

b) 您在 Node.JS 中編寫了一個轉換器以獲得正確的格式

c) 您使用 OPENSSL 之類的工具轉換文件。

在這里,我向您展示了“c-way”,因為您只處理一個密鑰對,並且可能不需要編程解決方案。

假設您有兩個文件,分別帶有私鑰(“rsa_privatekey_2048.der”)和公鑰(“rsa_publickey_2048.der”)。

在 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

將文件轉換為其 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:

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