【问题标题】:How Do I use RSA between Server and GWT Client?如何在服务器和 GWT 客户端之间使用 RSA?
【发布时间】:2014-11-04 19:16:12
【问题描述】:

我想加密 Java 服务器后端和 GWT 客户端之间的数据。在 GWT 客户端上,我使用 sbn.js 库。它的工作速度非常快,比gwt-crypto 快得多。

在给定 RSA (e,n) 的情况下,这是我在客户端加密的方式。我创建了一个JSFiddle

var n = "BC86E3DC782C446EE756B874ACECF2A115E613021EAF1ED5EF295BEC2BED899D26FE2EC896BF9DE84FE381AF67A7B7CBB48D85235E72AB595ABF8FE840D5F8DB";

var e = "3";
var d = "7daf4292fac82d9f44e47af87348a1c0b9440cac1474bf394a1b929d729e5bbcf402f29a9300e11b478c091f7e5dacd3f8edae2effe3164d7e0eeada87ee817b";

function do_encrypt() {
    var before = new Date();
    var rsa = new RSAKey();
    rsa.setPublic(n, e);
    var res = rsa.encrypt($("#plaintext").val());

    $("#ciphertext").val(res);
    $("#cipherb64").val(hex2b64(res));
    console.log("res");



}

$("#encrypt").click(function () {
    do_encrypt();
});

我使用要在服务器上解密的加密明文的十六进制表示。 这是我在服务器上解密的方法。

我使用以下库:

compile 'org.bouncycastle:bcprov-jdk15on:1.51'
compile 'org.bouncycastle:bcprov-ext-jdk15on:1.51'

这是我在服务器上使用 RSA 的 (d,n) 解密的方法:

    try {
        BigInteger modulus = new BigInteger("BC86E3DC782C446EE756B874ACECF2A115E613021EAF1ED5EF295BEC2BED899D26FE2EC896BF9DE84FE381AF67A7B7CBB48D85235E72AB595ABF8FE840D5F8DB",16);
        BigInteger exponent = new BigInteger("3");
        RSAKeyParameters publicKey = new RSAKeyParameters(false, modulus, exponent)

        BigInteger exponent2 = new BigInteger("7daf4292fac82d9f44e47af87348a1c0b9440cac1474bf394a1b929d729e5bbcf402f29a9300e11b478c091f7e5dacd3f8edae2effe3164d7e0eeada87ee817b", 16);
        RSAKeyParameters privateKey = new RSAKeyParameters(true, modulus, exponent2)

        String encryptedData = "a7f7d5c77c246729141cdfcc77f1f7b38d5f8066b0bc53b2e85119f3f1784f43be2140b5c382ad483bb57cc1b586962cbb1e831e6070a27e4880bbc549e20a372571d09c6b1269ddd7288916f10c96a9138f4165569c4767bfb489de2d44b450ed1495c99da985dc264dabadd9709ccd950ae55095373ccbc3344a26b3efd2dc";

        ////// decrypt
        AsymmetricBlockCipher d = new RSAEngine();
        d = new PKCS1Encoding(d);
        d.init(false, privateKey);

        byte[] messageBytes2 = new BigInteger(encryptedData,16).toByteArray();
        byte[] hexEncodedCipher2 = d.processBlock(messageBytes2, 0, messageBytes2.length); 


        println("encrypted:"+new String(hexEncodedCipher2));

    }
    catch(Exception e) {
        e.printStackTrace()
        println "#################### error"
    }

我遇到了以下异常:

Error |
org.bouncycastle.crypto.DataLengthException: input too large for RSA cipher.

我想那行 println("encrypted:"+new String(hexEncodedCipher2));是问题所在。

  1. 如何在客户端解密?

  2. 为什么每次我使用相同的 (e,n) 和相同的明文运行客户端加密时都会得到不同的加密?

【问题讨论】:

  • 1) 您的密码看起来太大了。它永远不应大于您的模数。 2)这就是它应该如何工作的,RSA加密使用一些随机填充,所以每次加密,即使是相同的明文,都会有所不同。此外,您应该只使用 bcprov-jdk15on 库,-ext 版本几乎相同,只是它包含一些您不需要的旧密码(如 IDEA)。
  • @GregS 您能否更正我的代码示例。
  • RSA(和任何公共密钥方案)被广泛用于加密将用于加密大量数据的对称密钥。对称密码确实比公钥密码快。混合方案是不错的选择。 stackoverflow.com/questions/118463/…

标签: java javascript html gwt encryption


【解决方案1】:

RSA 只能加密比密钥长度短的数据块。

因此您必须使用混合方案,即在 RSA 中加密一个随机密钥,该密钥将与 AES 等对称密码一起使用。

对于这个前任,我有很多主题:how to use RSA to encrypt files (huge data) in C#

接下来要去哪里? Javascript <-> Java AES

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 2011-02-10
    • 2023-03-12
    • 2018-01-06
    • 2015-06-08
    相关资源
    最近更新 更多