计算密码时的32位64位差异

时间:2013-09-02 17:30:20

标签: java encryption cryptography

我有一个简单的Xades / BES实现和两种情况。

  1. 在Windows 7 32Bit上 用java

    java version "1.7.0_25"
    Java(TM) SE Runtime Environment (build 1.7.0_25-b17)
    Java HotSpot(TM) Client VM (build 23.25-b01, mixed mode)
    
  2. 在Windows 2008 Server 64位上,使用相同的JVM。

  3. 我的应用程序在32位Windows 7上完美运行,但是当我尝试在Windows 2008 Server中运行已编译的代码时出现错误:

        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.doFinal(RSACipher.java:349)
        at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:382)
        at javax.crypto.Cipher.doFinal(Cipher.java:2087)
    

    有问题的代码字段如下:

        public static byte[] getDecryptedSignatureValue(XMLSignature signature) throws         XadesElementException, InvalidKeyException
    {
        byte[] signatureValue = null;
        try {
            KeyInfo keyInfo = signature.getKeyInfo();            
            PublicKey key = keyInfo.getPublicKey();            
            Cipher cipher = getCipher("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, key);
    
            signatureValue = signature.getSignatureValue();
            byte[] cipherData = cipher.doFinal(signatureValue);
            return cipherData;
    
        } catch (KeyResolverException | XMLSignatureException | IllegalBlockSizeException | BadPaddingException ex) {
            Logger.getLogger(KeyUtils.class.getName()).log(Level.SEVERE, null, ex);
            Logger.getLogger(KeyUtils.class.getName()).log(Level.SEVERE, null, "SignatureValue:"+ BaseUtils.toBase64String(signatureValue));
        } finally {
    
        }
        return null;
    
    }
    

    我唯一能想到的就是架构差异。我在这里错过了什么吗?可能是什么问题?

    提前致谢。

    修改 以下是我的新发现。 1.我已经在Windows 7 64位上测试了我的应用程序,并且在签名和验证时没有问题。 2.更有趣的是,我已经在另一台Windows 2008 Server 64位上测试了该应用程序,并且它取得了成功。

    我认为有一些配置设置,但我无法弄清楚是什么。

1 个答案:

答案 0 :(得分:1)

这可能是由于选择的提供商和/或提供商实施。请注意,用于加密的PKCS#1填充(EME-PKCS1-v1_5解码)和用于签名验证的PKCS#1填充(EMSA-PKCS1-v1_5编码)之间存在差异。某些提供商将根据密钥类型(公共或私有)选择填充,其他提供商将根据您使用CipherSignature来保留单个填充方案。

如果可能,请尝试使用Signature进行签名验证,而不是使用公钥进行Cipher解密。否则,请检查选择了哪些提供程序(使用例如Cipher.getProvider()并尝试查找有效的提供程序。请注意 - 正如您可能已经发现的那样 - 它取决于实现,而不是取决于接口规范,如果解密成功或失败。 / p>

所以目前它正试图解码这个:

EM = 0x00 || 0x02 || PS || 0x00 || M

随机,非零PS和消息M

但您希望验证这一点:

EM = 0x00 || 0x01 || PS || 0x00 || T

PS值为FF,T为ASN.1 DER编码算法OID和哈希值。