javax.crypto.BadPaddingException:数据必须以零开头

时间:2012-06-01 19:47:36

标签: java security rsa encryption

首先,这不是一个重复的问题。我面临一个非常奇怪的问题。

以下是我的工作。

案例1:

  1. 生成密钥对
  2. 使用私钥加密
  3. 使用公钥解密
  4. 一切正常。

    案例2:

    1. 从Mozila Firefox密钥库加载证书
    2. 使用证书A
    3. 使用证书A的私钥加密
    4. 使用证书A的公共Keu解密
    5. 一切正常。

      案例3:

      1. 从Internet Explorer密钥库加载证书
      2. 使用证书A
      3. 使用证书A的私钥加密
      4. 使用证书A的公共Keu解密
      5. 在Decrypt时间,我收到BadPadding异常错误

        以下是我的每个代码的摘要。

        生成密钥对

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

        加载Mozilla KeyStore

            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 = KeyStore.getInstance("Windows-MY");
            keyStore.load(null, null);
        

        从KeyStore获取公钥和私钥

            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;
        }
        

        异常Stacktrace

        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 个答案:

答案 0 :(得分:1)

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