use*_*751 5 java arrays encryption rsa bouncycastle
我试图使用java bouncy castle库来使用RSA来解密和解密一个短字节数组.我做了以下步骤:
我注意到原始和解密的数据数组不一样.解密的数据数组缺少第一个条目,因此比原始数据数组短1.仅当数据数组的第一个条目为"0"时才会发生这种情况.为什么会这样?解密不应该返回相同的数据数组吗?或者我对图书馆的假设,使用和理解是错误的?
这里是完整的测试用例(带有导入以便更好地理解):
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));
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助!
这是因为没有指定必须使用的填充机制;您要做的就是将填充机制留给提供者,在本例中为 Bouncy。Bouncy 似乎默认不使用填充机制。
在这种情况下,“RSA”运算的结果就是执行模幂运算(使用私有指数)时得到的数字。由于数字不是字节数组,因此必须将其转换为字节数组。由于数字的初始零的数量是未知的,因此它们被简单地去除。
为了避免这种情况(并按照定义使用 RSA,RSA需要 padding ),如果您想要更现代/安全的版本,请尝试使用"RSA/ECB/PKCS1Padding"或。"RSA/ECB/OAEPWithSHA-1AndMGF1Padding"众所周知,没有填充的 RSA 是不安全的。
想象一下,如果明文转换为数字 1 会发生什么。如果使用公共指数执行模幂,结果仍然只是 1。显然,这不是 RSA 的初衷。
如果没有随机填充,加密还具有令人讨厌的特性,即对于相同的密文加密为相同的结果(如果您有已知的密文,则加密"yes"或"no"很容易区分"yes")。
| 归档时间: |
|
| 查看次数: |
702 次 |
| 最近记录: |