加载在JSBN中创建的RSA公钥,然后加密消息
Load RSA public key created in JSBN, then encrypt a message
我正试图使用JSBN在JavaScript中创建一个RSA密钥对,并将公钥传输到Crypto++。然后,我试图用Crypto++加密一条消息,并将其发送回JavaScript并解密。
但我在这方面相对较新,所以我认为我做错了什么(数据没有被解密)
任何帮助都将不胜感激:D
这是我的cpp代码
Integer n(nStr->c_str()),
e("0x10001");
RSA::PublicKey pubKey;
pubKey.Initialize(n, e);
AutoSeededRandomPool rng;
if (!pubKey.Validate(rng, 3))
throw std::exception("Rsa private key validation failed");
////////////////////////////////////////////////
// Encryption
RSAES_PKCS1v15_Encryptor enc(pubKey);
StringSource ss1(data, true,
new PK_EncryptorFilter(rng, enc,
new StringSink(retStr)
));
std::string retData2 = "";
StringSource ss2((const byte*)retStr.data(), retStr.size(), true,
new Base64Encoder(
new StringSink(retData2)
));
retStr = retData2;
我的javascript代码
// nStr in CPP is "0x" + localStorage.getItem("rsa_public") from javascript
// data in CPP is "secret"
var rsa = new RSAKey();
var publickey = localStorage.getItem("rsa_public");
var privatekey = localStorage.getItem("rsa_private");
rsa.setPrivate(publickey, "10001", privatekey);
alert(b64tohex(dec) + "'n" + rsa.encrypt("secret")); <-- these don't match at all .. and ofc rsa.decrypt returns null
javascript中的dec是来自CPP 的retStr
JSBN和您的Crypto++代码使用的PKCS#1 v1.5填充是随机填充,因此如果您使用相同的密钥加密数据,它看起来会有所不同。您必须通过双向加密和解密来检查您的实现是否有效。
RSAES_PKCS1v15_Encryptor enc(pubKey);
StringSource ss1(data, true,
new PK_EncryptorFilter(rng, enc,
new StringSink(retStr)
));
...
StringSource ss2((const byte*)retStr.data(), retStr.size(), true,
new Base64Encoder(
new StringSink(retData2)
));
对于使用Javascript和JSBN进行互操作,我不确定这是否正确。单独使用它是正确的,而且对于与OpenSSL的互操作也是正确的。
Crypto++使用早期的Base64编码方案。它出现在当时的电子邮件和其他标准中(当时大约是20世纪90年代)。字母表使用加号(+)和正斜杠(/)字符。
Javascript和JSON技术,如JSON Web密钥(JWK),倾向于使用URL或Web安全字母表进行Base64编码。字母表使用减号(-)和下划线(_)字符。
旧的和新的Base64编码方案都在RFC 4648、Base16、Base32和Base64数据编码中指定。
您应该获取Base64URLEncoder的补丁,并将其应用于Crypto++源之上。修补后,您将拥有现有的Base6Encoder
和新的Base64URLEncoder
。最后,重新编译并重新安装库。您必须对其进行修补,因为它不是Wei Dai编写和提供的Crypto++库的一部分。
然后,执行以下操作:
RSAES_PKCS1v15_Encryptor enc(pubKey);
string encoded;
StringSource ss(data, true,
new PK_EncryptorFilter(prng, enc,
new Base64URLEncoder(
new StringSink(encoded)
)));
// Print encoded cipher text
cout << encoded << endl;
return encoded;
至于";这些根本不匹配"-我想这是意料之中的事。RSA加密使用随机填充,因此当您对m1
和m2
消息进行加密时,密文是不同的。它被称为";语义安全";这是一种强烈的(更强的?)安全概念。这样,坏人就无法判断同一条信息何时被发送了两次。
- 获取javascript中的公钥格式
- 如何使用html5生成临时公钥
- 加载在JSBN中创建的RSA公钥,然后加密消息
- Javascript Forge Crypto Library:重新创建公钥和私钥以供以后重用
- RSA 公钥与 JavaScript 和 C# 的兼容性
- JSBN/Forge是否可以用于生成RSA私钥/公钥对
- Javascript:向上和向下舍入到最接近的 5,然后找到一个公分母
- 从 N E D BIG INTS 生成序列化的 RSA 公钥/私钥
- 如何加载 PEM 格式的公钥以进行加密
- 用“加密”在Javascript中加密数据;RSACryptoServiceProvider”;公钥->超出最大异
- 使用openpgp.js计算公钥的密钥id
- Node.js:使用唯一的公钥认证客户端(类似于Github SSH密钥认证)
- 从其他地方导入公钥到CngKey
- jsrsign:不能用PEM RSA公钥验证JWT
- JSEncrypt每次为相同的消息和公钥生成不同的输出
- 从数字生成公钥
- 使用 CA 的公钥验证 .cer 使用 javascript 的文件
- 解析加密ECDH公钥为JWK格式,以使用它与WebCrypto
- Javascript ECDSA获取私钥和公钥
- 是否有可能修改事件数据在公共谷歌日历只使用公钥