我尝试在Java程序中实现RSA算法。我面临“BadPaddingException:数据必须从零开始”。 以下是用于加密和解密数据的方法:
public byte[] encrypt(byte[] input) throws Exception
{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");//
cipher.init(Cipher.ENCRYPT_MODE, this.publicKey);
return cipher.doFinal(input);
}
public byte[] decrypt(byte[] input) throws Exception
{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");///
cipher.init(Cipher.DECRYPT_MODE, this.privateKey);
return cipher.doFinal(input);
}
以这种方式从文件中读取privateKey和publicKey属性:
public PrivateKey readPrivKeyFromFile(String keyFileName) throws IOException {
PrivateKey key = null;
try {
FileInputStream fin = new FileInputStream(keyFileName);
ObjectInputStream ois = new ObjectInputStream(fin);
BigInteger m = (BigInteger) ois.readObject();
BigInteger e = (BigInteger) ois.readObject();
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
key = fact.generatePrivate(keySpec);
ois.close();
}
catch (Exception e) {
e.printStackTrace();
}
return key;
}
私钥和公钥以这种方式创建:
public void Initialize() throws Exception
{
KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
keygen.initialize(2048);
keyPair = keygen.generateKeyPair();
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pub = fact.getKeySpec(keyPair.getPublic(), RSAPublicKeySpec.class);
RSAPrivateKeySpec priv = fact.getKeySpec(keyPair.getPrivate(), RSAPrivateKeySpec.class);
saveToFile("public.key", pub.getModulus(), pub.getPublicExponent());
saveToFile("private.key", priv.getModulus(), priv.getPrivateExponent());
}
然后保存在文件中:
public void saveToFile(String fileName, BigInteger mod, BigInteger exp) throws IOException {
FileOutputStream f = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(f);
oos.writeObject(mod);
oos.writeObject(exp);
oos.close();
}
我无法弄清楚问题是如何产生的。任何帮助都会很感激!
提前致谢。
答案 0 :(得分:2)
原则上代码看起来还不行 - 我会进行一些登录以确保您生成的密钥真正是从文件中读取的密钥(您没有做一些愚蠢的事情,比如使用新密钥,然后尝试用旧密钥读取它,例如?)
答案 1 :(得分:0)
到目前为止,我已将此跟踪到CipherSpi.engineDoFinal()。为BadPaddingException提供的解释是
[当密码处于解密模式时抛出,并且已请求(un)填充,但解密的数据不受适当的填充字节限制
更具体的行为似乎与Spi有关。你知道你在使用什么Spi吗?只是默认的?
编辑:
不幸的是,我很难跟踪默认的Spi是什么。看起来它是在Cipher.java的chooseFirstProvider()
方法lines 644 to 721 here中选择的。如果你有一个方便的调试器,你可能想知道你有什么Spi,然后检查它的文档...但我仍然认为它更可能是输入的东西,而不是逻辑(我问过这个早些时候,在评论中)。