加载在JSBN中创建的RSA公钥,然后加密消息

时间:2015-03-01 08:27:44

标签: javascript c++ encryption rsa crypto++

我正在尝试使用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

dec in javascript是来自CPP的retStr

2 个答案:

答案 0 :(得分:2)

JSBN使用的PKCS#1 v1.5填充和您的Crypto ++代码是随机填充,因此如果使用相同的密钥加密数据,它将看起来不同。你必须检查你的实现是通过一端加密和另一端解密来实现的。

答案 1 :(得分:1)

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年代左右)都可以看到。字母表使用加号(+)和正斜杠(/)字符。

像JSON Web Keys(JWK)这样的Javascript和JSON技术倾向于使用URL或Web Safe字母表来支持Base64编码。字母表使用减号( - )和下划线(_)字符。

旧的和新的Base64编码方案都在RFC 4648, The Base16, Base32, and Base64 Data Encodings中指定。

您应该获取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;

至于&#34;这些根本不匹配......&#34; - 我认为这是预料之中的。 RSA加密使用随机填充,以便在加密消息 m1 m2 时,密文不同。它被称为&#34;语义安全&#34;它是一个强大的(更强大的)安全概念。通过这种方式,坏人无法判断同一消息何时被发送两次。