【问题标题】:RSA encrypt with BouncyCastle API使用 BouncyCastle API 进行 RSA 加密
【发布时间】:2018-02-26 17:05:32
【问题描述】:

我想在 Java 中使用带有 BouncyCastle API 的 RSA 加密文件时遇到问题。问题如下:在下面的代码中,我创建 RSAKeyParameters 对象的行,它的构造函数询问我三个参数:
1.如果我们想用公钥或私钥加密。
2. 具有键模数的 BigInteger。
3. 具有键指数的 BigInteger。

我的方法接收的第一个参数是包含密钥的文件。那么在 RSAKeyParameter 的构造函数中,如何传递一个 BigInteger 即模数和指数?如何从文件中获取模数和指数?

PD:包含密钥的文件有一个CR和LF,这就是为什么有两个readLine()。

void cifrar_asimetrica(String fichClave, String archivoClaro, String result, boolean conPrivada){

    byte[] modulo;
    byte[] exponente;

    try(
        BufferedReader lectorClave = new BufferedReader (new FileReader(fichClave));
        BufferedInputStream lectorFichero = new BufferedInputStream(new FileInputStream(archivoClaro));
        BufferedOutputStream fsalida = new BufferedOutputStream(new FileOutputStream(result))){

        modulo = Hex.decode(lectorClave.readLine()); 
        exponente = Hex.decode(lectorClave.readLine());


        RSAEngine cifrador = new RSAEngine();
        CipherParameters parametro = new RSAKeyParameters(conPrivada, new BigInteger(modulo.toString()), new BigInteger(exponente.toString()));

        cifrador.init(true,parametro); // vamos a cifrar

        byte[] datosLeidos = new byte[cifrador.getOutputBlockSize()];
        byte[] datosCifrados = new byte[cifrador.getOutputBlockSize()];
        int leidos = 0;
        //NO SE SI ES GETINPUTBLOCKSIZE O OUTPUT
        leidos = lectorFichero.read(datosLeidos, 0, cifrador.getOutputBlockSize());

        while(leidos > 0){
            datosCifrados = cifrador.processBlock(datosLeidos, 0, cifrador.getOutputBlockSize());
            fsalida.write(datosCifrados, 0, datosCifrados.length);
            leidos = lectorFichero.read(datosLeidos, 0, cifrador.getOutputBlockSize());
        }

    }catch(Exception e){
        e.printStackTrace();
    }
}

【问题讨论】:

  • 请注意,要加密的数据大小限制为小于 RSA 的密钥大小。如果您确实需要 RSA(非对称加密)和大于密钥大小的数据,则可能需要混合加密。

标签: java encryption rsa bouncycastle public-key-encryption


【解决方案1】:

如果从文件中的十六进制转换而来的字节数组是传统的大端字节数组,要将正大端字节数组转换为 BigInteger,请查看 the javadoc for BigInteger 的构造函数,该构造函数采用 int 符号表示正数和大小的大端字节数组。

“教科书”(未填充)RSA 不安全;请参阅 crypto.SX security.SX 和维基百科。以您编码的方式对大于一个块的数据使用 RSA 将半随机地失败,如果您纠正了这一点,那么相当于 ECB 模式的方式是低效且不安全的;请参阅 crypto.SX security.SX 和维基百科。使用未经身份验证的公钥通常是不安全的。

如果您这样做是为了好玩,因为它让您感觉自己像一个“l33t hack5r”或邦德超级恶棍,并且不关心实际的安全性,这很好。如果您需要或想要真正的安全性,请放弃它并使用由知道自己在做什么的人编写的程序,和/或搜索“不要推出自己的加密货币”。

【讨论】:

    【解决方案2】:

    您当前在字节数组上使用toString。这只会返回对象引用的代表,与数组中的值关系不大。

    相反,您可以使用BigInteger constructor that takes a string and radix,使用 16 作为基数。请确保您在十六进制表示中没有任何虚假或无效字符。

    【讨论】:

    • 是的,请听从 Dave 的建议,不要使用教科书 RSA:需要安全填充模式,首选 OAEP。
    • 是的,我解决了,我使用了 PKCS1 编码。有一个接收字节数组的 BigInteger 构造函数,我不知道!但无论如何,谢谢。顺便说一句,我是学生,我正在学习,所以如果我觉得自己像个 leet 黑客或类似的东西,请不要这样做
    • @victor26567 我已经重读了我的答案,我没有看到任何暗示你是黑客的东西。请注意,在开发人员圈子中,黑客攻击与破解或执行非法活动不同。我的平板电脑目前正在喷出滑翔机标志,我正在焦急地等待我的终极黑客键盘。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    • 2012-05-22
    相关资源
    最近更新 更多