当前位置: 首页 > 知识库问答 >
问题:

当数据数组的第一个条目为零时,使用RSA加密获得太短的数组

吴子昂
2023-03-14

我试图使用java bouncy castle库对一个短字节数组进行RSA加密和解密。我做了以下几个步骤:

  1. 生成2048位密钥对。
  2. 创建一个短数据字节数组,其中第一个条目为零。
  3. 使用生成的密钥和RSA加密数据数组。
  4. 使用生成的密钥和RSA解密加密的数据数组
  5. 比较原始数据数组和解密数据数组。

这里是完整的测试用例(为了更好地理解,有导入):

import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.provider.JDKKeyPairGenerator;
import org.bouncycastle.util.encoders.Hex;
import org.hive2hive.core.H2HJUnitTest;
import org.junit.Test;

public class EncryptionUtil2Test {

    @Test
    public void testBug() throws IOException, InvalidKeyException, IllegalBlockSizeException,
        BadPaddingException, DataLengthException, IllegalStateException, InvalidCipherTextException,
        NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
        InvalidAlgorithmParameterException {

        Security.addProvider(new BouncyCastleProvider());

        // generate RSA keys
        BigInteger publicExp = new BigInteger("10001", 16); // Fermat F4, largest known fermat prime
        JDKKeyPairGenerator gen = new JDKKeyPairGenerator.RSA();
        RSAKeyGenParameterSpec params = new RSAKeyGenParameterSpec(2048, publicExp);
        gen.initialize(params, new SecureRandom());
        KeyPair keyPair = gen.generateKeyPair();

        // some data where first entry is 0
        byte[] data = { 0, 122, 12, 127, 35, 58, 87, 56, -6, 73, 10, -13, -78, 4, -122, -61 };

        // encrypt data asymmetrically
        Cipher cipher = Cipher.getInstance("RSA", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
        byte[] rsaEncryptedData = cipher.doFinal(data);

        // decrypt data asymmetrically
        cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
        byte[] dataBack = cipher.doFinal(rsaEncryptedData);

        System.out.println("data      = " + Hex.toHexString(data));
        System.out.println("data back = " + Hex.toHexString(dataBack));

        assertTrue(Arrays.equals(data, dataBack));

    }

}

谢谢你的帮助!

共有1个答案

殷宾白
2023-03-14

这是由于没有指定必须使用的填充机制;您所做的是将填充机制留给提供者,在本例中是弹性的。Bouncy似乎默认不使用填充机制。

在这种情况下,“rsa”操作的结果只是在执行模幂运算(使用私有指数)时得到的数字。由于数字不是字节数组,所以必须将其转换为字节数组。由于初始零的个数对于一个数字来说是未知的,所以这些零的个数被简单地去掉。

若要避免这种情况(并按定义使用RSA,RSA需要填充),请尝试使用“RSA/ecb/pkcs1padding”“RSA/ecb/oaepwithsha-1andmgf1padding”。已知没有填充的RSA是不安全的。

如果没有随机填充,加密还具有对相同密文加密到相同结果的讨厌特性(如果您对“yes”有已知密文,那么对“yes”“no”进行加密就很容易区分)。

 类似资料:
  • 我的问题是: 我的加密代码在64个字符以下运行良好。但如果超过64个字符,我会得到以下错误 加密代码 密钥生成代码 我的问题是: 可以用512位密钥加密大文本吗?我的密码有错吗? 注意:如果有人想要完整的代码,我会稍后更新。

  • 我用RSA加密来加密C#中的一些数据。现在我想用Java解密加密的数据。但是我遇到了一些问题。 主要问题可能是将加密消息从c#获取到java。在c#中,我们有无符号字节,字节序是不同的 因此,为了进行测试,我将c#中加密数据的数组转换为数组并获得它的字符串表示形式。然后我将字节数组的字符串表示形式复制到我的java代码中并将其转换回“字节”数组。之后,我反转数组以匹配java的endianess。

  • 我正在使用OpenSSL RSA API用服务器的公钥加密数据。 我使用的是,所以RSA应该可以轻松地用256字节的公钥加密255字节。但我收到了: 我改变dl(data_lenght)到256(只有1),我得到了这个: 我知道RSA可以用256个密钥编码255个字节。有什么问题吗?

  • 本文向大家介绍java使用RSA加密方式实现数据加密解密的代码,包括了java使用RSA加密方式实现数据加密解密的代码的使用技巧和注意事项,需要的朋友参考一下 RSA的应用 RSA是一种非对称加密算法。现在,很多登陆表单的密码的都采用RSA加密,例如京东中的登陆使用公钥对密码进行加密 java使用RSA加密方式实现数据加密解密,需要首先产生私钥和公钥 测试代码 RSA工具类的实现 总结 以上所述是

  • 我正在android studio上制作一个支持Firebase的应用程序。它当前将有关用户的信息存储在Firebase数据库中自己上传的部分中。它存储在使用其Firebase帐户的uuid的结构中,并将其所有上载内容放在该结构下,即图片、提醒、注释和密码。 我想加密数据库中的密码部分,这样即使我也无法读取它。当我说密码部分时,我指的是应用程序中允许用户为其他事情存储自己新生成的密码的部分;不是他

  • 问题内容: 我有一个数组: 我想获得此数组的第一个元素。预期结果: 字符串 一个要求: 它不能通过引用传递来完成 ,所以不是一个好的解决方案。 我怎样才能做到这一点? 问题答案: 原始答案,但代价昂贵(O(n)): 在O(1)中: 其他用例等 如果修改(就重置数组指针而言)不是问题,则可以使用: 如果需要数组“副本”,则从理论上讲应该更有效: 使用PHP 5.4+(但如果为空,则可能导致索引错误)