2012-06-01 37 views
1

首先,这不是重复的问题。我面临一个很奇怪的问题。javax.crypto.BadPaddingException:数据必须以零开头

以下是我所做的。

案例1:

  1. 生成密钥对
  2. 加密使用私钥
  3. 解密使用公共密钥

,一切工作正常。

案例2:

  1. 加载证书从Mozila Firefox的密钥存储
  2. 使用证书
  3. 加密使用使用公共KEU证书的
  4. 证书
  5. 解密私钥

一切工作正常。

案例3:

  1. 从Internet Explorer密钥存储
  2. 使用证A负载证书
  3. 加密使用证书的私钥
  4. 解密使用证书的公共KEU一个

在Decrypt时间,我得到BadPadding的错误ex ception

以下是我的每个代码的片段。

生成密钥对

KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair(); 
    PublicKey publicKey = keyPair.getPublic(); 
    PrivateKey privateKey = keyPair.getPrivate(); 

负载Mozilla的密钥库

String strCfg = System.getProperty("user.home")+ File.separator + "jdk6-nss-mozilla.cfg"; 
    Provider p1 = new sun.security.pkcs11.SunPKCS11(strCfg); 
    Security.addProvider(p1); 
    keyStore = KeyStore.getInstance("PKCS11"); 
    keyStore.load(null, "password".toCharArray()); 

配置文件的内容

name=NSS 
slot=2 
library=C:/Program Files/Mozilla Firefox/softokn3.dll 
nssArgs="configDir='C:/Documents and Settings/pratik.vohera.DIGI-CORP/Application Data/Mozilla/Firefox/Profiles/t48xsipj.default' certPrefix='' keyPrefix=''  secmod='secmod.db' flags=readOnly" 

负载IE密钥库

keyStore = KeyStore.getInstance("Windows-MY"); 
    keyStore.load(null, null); 

从密钥库获取公钥和私钥

if (keyStore != null) { 
    Enumeration<String> enumaration = null; 
    try { 
     enumaration = keyStore.aliases(); 
    } catch (KeyStoreException e1) { 
     e1.printStackTrace(); 
    } 
    ArrayList<String> certiList; 
    while (enumaration.hasMoreElements()) { 
     String aliases = enumaration.nextElement(); 
     certiList = new ArrayList<String>(); 
     certiList.add(aliases); 
     try { 
      selectedCert = keyStore.getCertificate(aliases); 
      selectedpublickey = (RSAPublicKey) selectedCert.getPublicKey(); 
      selectedAlias = aliases; 
      selectedprivateKey = (PrivateKey) keyStore.getKey(selectedAlias, null);} 
     } catch (KeyStoreException e) { 
      e.printStackTrace(); 
     } 
    } 

加密

private static String publicEncrypt(String text, Key pubKey) throws Exception { 
    BASE64Encoder bASE64Encoder = new BASE64Encoder(); 
    byte[] plainText = text.getBytes(); 
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
    cipher.init(Cipher.ENCRYPT_MODE, pubKey); 
String encryptedText = bASE64Encoder.encode(cipher.doFinal(plainText)); 
return encryptedText; 
} 

解密

private static String privateDecrypt(String text, Key priKey)throws Exception  { 
    BASE64Decoder base64Decoder = new BASE64Decoder(); 
byte[] encryptText = base64Decoder.decodeBuffer(text); 
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
cipher.init(Cipher.DECRYPT_MODE, priKey); 
String decryptedString = new String(cipher.doFinal(encryptText)); 
return decryptedString; 
} 

异常堆栈跟踪

javax.crypto.BadPaddingException: Data must start with zero 
at sun.security.rsa.RSAPadding.unpadV15(Unknown Source) 
at sun.security.rsa.RSAPadding.unpad(Unknown Source) 
at com.sun.crypto.provider.RSACipher.a(DashoA13*..) 
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..) 
at javax.crypto.Cipher.doFinal(DashoA13*..) 
at test.testclass.privateDecrypt(testclass.java:198) 
at test.testclass.test(testclass.java:137) 
at test.testclass.main(testclass.java:120) 

我一直在这个很长一段时间。这个非常重要。请告诉我是否需要更多信息。

+1

您不用私钥加密。您使用某人的公钥对消息进行加密,然后用私钥对其进行解密。这样私人密钥保持私密。你可以使用私钥对消息进行签名,但那不同,而不是你的代码看起来在做什么。你想做什么 ?最后,在案例3中,它看起来像你说你使用一个证书进行加密,而另一个证书进行解密。这是否准确,如果是的话,为什么? – imichaelmiers

+0

你能给我们举一个你的加密函数的输出结果的例子吗? –

+0

几乎可以肯定你没有使用属于同一对的公钥/私钥。 –

回答

1

在第三种情况下,问题是:您尝试使用私钥进行加密,并使用错误的公钥进行解密。你应该总是使用私钥解密。

相关问题