4

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

  1. 在带有 java 的 Windows 7 32Bit 上

    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。

我的应用程序在 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 位上测试了该应用程序,并且成功运行。

我认为有些东西有一个配置设置,但我不知道是什么。

4

1 回答 1

1

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

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

所以目前它正在尝试对此进行解码:

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

带有随机的非零 PS 和消息 M

但是,您希望验证这一点:

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

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

于 2013-09-02T21:20:24.027 回答