javascript - Puttygen 和 NodeJS 上生成的 RSA 密钥的长度不同
问题描述
我一直在尝试在 AWS Lambda 上生成一个 RSA 密钥对,以替换当前在 PuTTYgen 上手动生成的密钥。PuTTYgen 上生成的密钥是 RSA 类型,长度为 2048,生成的示例密钥(无注释)如下 -
---- BEGIN SSH2 PUBLIC KEY ----
Comment: ""
AAAAB3NzaC1yc2EAAAABJQAAAQEAjloNCA4mycem+WTb49zUhYK7aRmg1uuorUvD
7GzE97C9EmmhUrVbp4d5dWF8zkT2sh5mRFrAnsSogxEtCzvh59mzbqUj+3Xw+xqJ
DMrHmnT8XKIGep++v3e+SV7RLio06ymp0H7zyHhbxLhZEnpGEKwkXmY53+RSUF7s
wfmvxS5mCo7677lbIZxGvvx65tT5as5m+ng7tKlqDAliuPl2vslyFhQw9B49cvOx
Z+UekK2iHD+DNCMQyxEelOru9YMwRozOwgtWPEyHcLinonAn2fUne28POsT3zXbv
rW10hkGH5JIHzGUoPxP6N7RRCnSN/NgS8rrHs51Skvhl0WzV6w==
---- END SSH2 PUBLIC KEY ----
现在我一直在尝试使用以下代码在 NodeJS lambda 上复制相同的内容 -
const generation = util.promisify(crypto.generateKeyPair);
const result = await generation('rsa',{
modulusLength: 2048,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
}
});
console.log(result['publicKey']);
console.log(result['privateKey']);
在执行这个 lambda 时,生成的公钥看起来像这样 -
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnF1VDHq0vu5iL0nkbum8
cVzdhxiqmR6XcZbcsilF+Se6tlS9VAbN8QTTLdqwhJ5Dw7DvBGUXpCqUIqyT5IU5
wjQGnWHAWhPmalAgYWDwwdiOxxgd6NnNRR2Q5P4PSruxvFG7BtiSKGXSZpMzTIyZ
sXajEY2vhkf77bMEgzJhpXGAvzZsGEDi9jni8FCabVH6jvXh/svpmoCxwhQY1HHh
9RksscuAfllMwOE4uiQvfq6CpPNJUwU4kWtiaAtgX26nnPvqaUX52xMuYBrWQI2m
vUiXuxynqnrVSAFt/QY/0lMKRgnzwkq6YTIf8PeMQQA6TVQbtGN+j0MFQJDxF2/l
dQIDAQAB
-----END PUBLIC KEY-----
据我了解 RSA 密钥,第一行和最后一行应该没有任何区别,因为它们基本上是注释。但是我看到 PuTTYgen 键包含大约 5 和 1/2 行内容,而 NodeJS 键包含 6 行以上的内容。当它们的长度都是2048时,为什么两者之间存在差异?
谢谢你。
解决方案
感谢您的评论,帮助我更好地理解键的格式。使用 NodeJS 代码生成的密钥是 PEM 格式,需要将其转换为 OpenSSH 格式以匹配来自 PuTTYgen 的输出密钥。
模块sshpk有助于将 PEM 密钥转换为 OpenSSH 格式。执行此操作的代码如下 -
var sshpk = require('sshpk');
let pemPublicKey = sshpk.parseKey(publicKey, 'pem');
let openSSHPublicKey = pemPublicKey.toString('ssh');
console.log(openSSHPublicKey);
这将产生具有以下格式的密钥 -
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqWWfYMm/q1Ee4AzRJMc+BgsqzVIZgwTidGDb6E3V2EQ85+iX09pmDF8E23Fsmd9WoUMB2L/FXUIlWZmofPmoInKk740UcsQGT0MVYQfDAiVBqrbymIR/lMBCirFpFq7hIDzACgWYAmSEFtDBdP4LmFozx6Vi3+Ss5g8EjkXcDLkPiBSM8YjCQO6CraH1dMIC4/hywitL1G2rngFdwgFAuG1HEqgXZKRZAm2043OVY2SDVnMvHcYjarPk94BydZ7mzZRCdaetDY73+8opVL0uRol2GfYwAoediz65iIm183w4p4F3JH09W4xSoT8FeTRfIc2iAlde3wFA6aK/NV0G5 (unnamed)
parseKey()
使用该方法时,可以通过添加名称来删除末尾的(未命名) 。
现在,您可以根据您的要求格式化此字符串,如下所示 -
let openSSHPublicKeyMaterial = openSSHPublicKey.split(" ")[1];
let formattedSSH2KeyArray = []
formattedSSH2KeyArray.push('---- BEGIN SSH2 PUBLIC KEY ----');
formattedSSH2KeyArray.push('Comment: ""');
for (let index = 0; index <= openSSHPublicKeyMaterial.length; index += 64 ) { // 64 corresponds to the number of characters in a single line
let singleLine = openSSHPublicKeyMaterial.substring(index, index + 64);
formattedSSH2KeyArray.push(singleLine);
}
formattedSSH2KeyArray.push('---- END SSH2 PUBLIC KEY ----');
let formattedSSH2Key = formattedSSH2KeyArray.join('\n');
console.log(formattedSSH2Key);
上述部分的执行将为您提供所需格式的密钥 -
---- BEGIN SSH2 PUBLIC KEY ----
Comment: ""
AAAAB3NzaC1yc2EAAAADAQABAAABAQCqWWfYMm/q1Ee4AzRJMc+BgsqzVIZgwTid
GDb6E3V2EQ85+iX09pmDF8E23Fsmd9WoUMB2L/FXUIlWZmofPmoInKk740UcsQGT
0MVYQfDAiVBqrbymIR/lMBCirFpFq7hIDzACgWYAmSEFtDBdP4LmFozx6Vi3+Ss5
g8EjkXcDLkPiBSM8YjCQO6CraH1dMIC4/hywitL1G2rngFdwgFAuG1HEqgXZKRZA
m2043OVY2SDVnMvHcYjarPk94BydZ7mzZRCdaetDY73+8opVL0uRol2GfYwAoedi
z65iIm183w4p4F3JH09W4xSoT8FeTRfIc2iAlde3wFA6aK/NV0G5
---- END SSH2 PUBLIC KEY ----
推荐阅读
- reactjs - 在 React 中使用 HOC 时如何屏蔽属性?
- laravel - 如何在 Laravel 中控制对另一台服务器上文件的访问
- vba - 如何绕过 VBA 批量替换功能的 255 个字符限制?
- android - 一个典型的android应用程序使用多少内存是合理的
- kubernetes - Helm 推荐方法中的持久卷、声明和副本
- android - 在 android 可绘制项目部分从 mipmap 添加图像
- javascript - REST API 使用 Swagger 和 Node.js 以及 SQL Server 作为数据库
- c++ - 使用某个宏时如何禁止调用特定函数
- java - 使用 POSTGRES 和 eclipselink 的 JPA 日期截断组
- docker - Jenkins 文件图像标记参数不起作用