首页 > 解决方案 > 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时,为什么两者之间存在差异?

谢谢你。

标签: javascriptaws-lambdacryptographyrsassh-keys

解决方案


感谢您的评论,帮助我更好地理解键的格式。使用 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 ----

推荐阅读