使用 WebCrypto API 生成 RSA 密钥对并使用密码保护它
Generate RSA key pair using WebCrypto API and protect it with passphrase
标题说明了一切。我想知道如何使用 WebCrypto API 生成 RSA 密钥对以及如何使用密码保护它以便将其存储在数据库中。
您可以使用 WebCrypto 生成 RSA 密钥对并将其导出 为 jwk(Json Web 密钥)、pkcs#8(私有)或 spki(public).请参阅 SubtleCrypto.exportKey() 和下面的示例代码
要以受保护的方式将密钥导出到外部系统,您可以使用如下标准:
PKCS#8: IETF Public Key-Cryptographic Standard Encryption #8. 处定义的 PKCS#8 私钥格式允许使用密码加密,但 WebCryptography exportKey 不支持它。它提供 PrivateKeyInfo
PKCS#12: PKCS#12 是一种密钥库交换格式。它可以包含私钥、带有 public 密钥的证书和证书链。内容使用密码进行 3DES 加密。通常找到扩展名为 .pfx 或 .p12
的文件
遗憾的是 WebCrypto 不支持以加密的通用格式导出,例如 PKCS#8 - 加密或 PKCS#12。您可以使用 forge
等第三方库以其中一种格式导出密钥
示例代码
WebCrypto RSASSA-PKCS1-v1_5 - 生成密钥
window.crypto.subtle.generateKey(
{
name: "RSASSA-PKCS1-v1_5",
modulusLength: 2048, //can be 1024, 2048, or 4096
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
},
true, //whether the key is extractable (i.e. can be used in exportKey)
["sign", "verify"] //can be any combination of "sign" and "verify"
)
.then(function(key){
//returns a keypair object
console.log(key);
console.log(key.publicKey);
console.log(key.privateKey);
})
.catch(function(err){
console.error(err);
});
WebCrypto RSASSA-PKCS1-v1_5 - exportKey
window.crypto.subtle.exportKey(
"pkcs8", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
privateKey //can be a publicKey or privateKey, as long as extractable was true
)
.then(function(keydata){
//returns the exported key data
console.log(keydata);
})
.catch(function(err){
console.error(err);
});
锻造 -PKCS#8
//needed: wrap webcrypto pkcs#8 to forge privateKey (see doc)
// encrypts a PrivateKeyInfo and outputs an EncryptedPrivateKeyInfo
var encryptedPrivateKeyInfo = pki.encryptPrivateKeyInfo(
privateKeyInfo, 'password', {
algorithm: 'aes256', // 'aes128', 'aes192', 'aes256', '3des'
});
// 将 EncryptedPrivateKeyInfo 转换为 PEM
var pem = pki.encryptedPrivateKeyToPem(encryptedPrivateKeyInfo);
锻造 - PKCS#12
//needed: wrap webcrypto pkcs#8 to forge privateKey (see doc)
// generate a p12 that can be imported by Chrome/Firefox
// (requires the use of Triple DES instead of AES)
var p12Asn1 = forge.pkcs12.toPkcs12Asn1(privateKey, certChain, password, {algorithm: '3des'});
// base64-encode p12
var p12Der = forge.asn1.toDer(p12Asn1).getBytes();
var p12b64 = forge.util.encode64(p12Der);
下载这个名为 OpenCrypto 的小型加密库,它允许您使用密码将私钥加密为 PKCS #8 RFC 5208 EncryptedPrivateKeyInfo 格式。库仅使用普通 JavaScript、WebCrypto API 和 Promises。
这里是图书馆的 link:https://github.com/PeterBielak/OpenCrypto
根据麻省理工学院的许可,该库可免费用于商业用途。享受! ;)
这是一个简单的例子:
var crypt = new OpenCrypto();
crypt.getKeyPair().then(function(keyPair) {
crypt.encryptPrivateKey(keyPair.privateKey,'securepassword').then(function(encryptedPrivateKey) {
// This PEM Encrypted Private Key is fully compatiable with OpenSSL
console.log(encryptedPrivateKey);
});
});
标题说明了一切。我想知道如何使用 WebCrypto API 生成 RSA 密钥对以及如何使用密码保护它以便将其存储在数据库中。
您可以使用 WebCrypto 生成 RSA 密钥对并将其导出 为 jwk(Json Web 密钥)、pkcs#8(私有)或 spki(public).请参阅 SubtleCrypto.exportKey() 和下面的示例代码
要以受保护的方式将密钥导出到外部系统,您可以使用如下标准:
PKCS#8: IETF Public Key-Cryptographic Standard Encryption #8. 处定义的 PKCS#8 私钥格式允许使用密码加密,但 WebCryptography exportKey 不支持它。它提供 PrivateKeyInfo
PKCS#12: PKCS#12 是一种密钥库交换格式。它可以包含私钥、带有 public 密钥的证书和证书链。内容使用密码进行 3DES 加密。通常找到扩展名为 .pfx 或 .p12
的文件
遗憾的是 WebCrypto 不支持以加密的通用格式导出,例如 PKCS#8 - 加密或 PKCS#12。您可以使用 forge
等第三方库以其中一种格式导出密钥示例代码
WebCrypto RSASSA-PKCS1-v1_5 - 生成密钥
window.crypto.subtle.generateKey(
{
name: "RSASSA-PKCS1-v1_5",
modulusLength: 2048, //can be 1024, 2048, or 4096
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
},
true, //whether the key is extractable (i.e. can be used in exportKey)
["sign", "verify"] //can be any combination of "sign" and "verify"
)
.then(function(key){
//returns a keypair object
console.log(key);
console.log(key.publicKey);
console.log(key.privateKey);
})
.catch(function(err){
console.error(err);
});
WebCrypto RSASSA-PKCS1-v1_5 - exportKey
window.crypto.subtle.exportKey(
"pkcs8", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
privateKey //can be a publicKey or privateKey, as long as extractable was true
)
.then(function(keydata){
//returns the exported key data
console.log(keydata);
})
.catch(function(err){
console.error(err);
});
锻造 -PKCS#8
//needed: wrap webcrypto pkcs#8 to forge privateKey (see doc)
// encrypts a PrivateKeyInfo and outputs an EncryptedPrivateKeyInfo
var encryptedPrivateKeyInfo = pki.encryptPrivateKeyInfo(
privateKeyInfo, 'password', {
algorithm: 'aes256', // 'aes128', 'aes192', 'aes256', '3des'
});
// 将 EncryptedPrivateKeyInfo 转换为 PEM var pem = pki.encryptedPrivateKeyToPem(encryptedPrivateKeyInfo);
锻造 - PKCS#12
//needed: wrap webcrypto pkcs#8 to forge privateKey (see doc)
// generate a p12 that can be imported by Chrome/Firefox
// (requires the use of Triple DES instead of AES)
var p12Asn1 = forge.pkcs12.toPkcs12Asn1(privateKey, certChain, password, {algorithm: '3des'});
// base64-encode p12
var p12Der = forge.asn1.toDer(p12Asn1).getBytes();
var p12b64 = forge.util.encode64(p12Der);
下载这个名为 OpenCrypto 的小型加密库,它允许您使用密码将私钥加密为 PKCS #8 RFC 5208 EncryptedPrivateKeyInfo 格式。库仅使用普通 JavaScript、WebCrypto API 和 Promises。
这里是图书馆的 link:https://github.com/PeterBielak/OpenCrypto 根据麻省理工学院的许可,该库可免费用于商业用途。享受! ;)
这是一个简单的例子:
var crypt = new OpenCrypto();
crypt.getKeyPair().then(function(keyPair) {
crypt.encryptPrivateKey(keyPair.privateKey,'securepassword').then(function(encryptedPrivateKey) {
// This PEM Encrypted Private Key is fully compatiable with OpenSSL
console.log(encryptedPrivateKey);
});
});