RSA BadPaddingException:数据必须以零开头

我尝试在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(); } 

我无法弄清楚问题是如何产生的。 任何帮助将不胜感激!

提前致谢。

原则上代码看起来没问题 – 我会进行一些登录以确保您生成的密钥真正是从文件中读取的密钥(您没有做一些愚蠢的事情,比如使用新密钥生成数据,然后尝试用旧的读取它,例如?)

到目前为止,我已将其跟踪到CipherSpi.engineDoFinal() 。 为BadPaddingException提供的解释是

[当密码处于解密模式时抛出,并且已请求(un)填充,但解密数据不受适当填充字节的限制

更具体的行为似乎是Spi依赖的。 你知道你在用什么Spi吗? 只是默认?

编辑:不幸的是,我很难追踪默认的Spi是什么。 它看起来像是在Cipher.java的chooseFirstProvider()方法中选择的, 这里是644到721行 。 如果你有一个方便的调试器,你可能想知道你有什么Spi,然后查看它的文档…但我仍然认为它更可能是输入的东西,而不是逻辑(我问过这个早些时候,在评论中)。