java RSA BadPaddingException:数据必须从零开始
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2714327/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RSA BadPaddingException : data must start with zero
提问by Robin Monjo
I try to implement an RSA algorithm in a Java program. I am facing the "BadPaddingException : data must start with zero". Here are the methods used to encrypt and decrypt my data :
我尝试在 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 and publicKey attributes are read from files this way :
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;
}
Private key and Public key are created this way :
私钥和公钥是这样创建的:
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());
}
and then saved in files :
然后保存在文件中:
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();
}
I can't figured out how the problem come from. Any help would be appreciate !
我想不通问题是怎么来的。任何帮助将不胜感激!
Thanks in advance.
提前致谢。
采纳答案by Neil Coffey
In principle the code looks OK -- I would put some logging in to make sure the key you're generating is genuinely the one that is then read from the file (you're not doing something silly like generating data with a new key, then trying to read it with an old one, for example?)
原则上,代码看起来没问题——我会进行一些登录以确保您生成的密钥确实是然后从文件中读取的密钥(您没有做一些愚蠢的事情,例如使用新密钥生成数据,然后尝试用旧的阅读它,例如?)
回答by Pops
So far, I've tracked this down to CipherSpi.engineDoFinal(). The explanation provided for BadPaddingException is
到目前为止,我已经将其追溯到CipherSpi.engineDoFinal()。为 BadPaddingException 提供的解释是
[Thrown when the] cipher is in decryption mode, and (un)padding has been requested, but the decrypted data is not bounded by the appropriate padding bytes
[当] 密码处于解密模式时抛出,并且已请求(取消)填充,但解密的数据不受适当的填充字节的限制
More specific behavior seems to be Spi-dependent. Do you know what Spi you're using? Just the default?
更具体的行为似乎依赖于 Spi。你知道你用的是什么Spi吗?只是默认?
EDIT:
Unfortunately, I'm having a hard time tracking down what the default Spi is. It looks like it's chosen in Cipher.java's chooseFirstProvider()method, lines 644 to 721 here. If you have a debugger handy, you might want to find out what Spi you have, then check the documentation for it... but I still think it's more likely that something's going on with the input, not the logic (I asked about that earlier, in a comment).
编辑:不幸的是,我很难找到默认的 Spi 是什么。看起来它是在 Cipher.java 的chooseFirstProvider()方法中选择的,这里的第 644 行到 721 行。如果你有一个方便的调试器,你可能想找出你有什么 Spi,然后检查它的文档......但我仍然认为更有可能是输入而不是逻辑发生了什么(我问过那个早些时候,在评论中)。

