Java pkcs7文件验证的问题
我对PKCS7证券文件有一个大而奇怪的问题。 我创建了一个p7s文件,就像在创建文件的地方建议的那样,并仅使用sun库对其进行验证。它很好用。Java pkcs7文件验证的问题,java,security,validation,x509certificate,pkcs#7,Java,Security,Validation,X509certificate,Pkcs#7,我对PKCS7证券文件有一个大而奇怪的问题。 我创建了一个p7s文件,就像在创建文件的地方建议的那样,并仅使用sun库对其进行验证。它很好用。 当我想要验证此文件时,问题开始出现。它返回此异常: java.security.SignatureException:签名编码错误 位于sun.security.rsa.RSASignature.engineVerify(RSASignature.java:185) 位于java.security.Signature$Delegate.engineVer
当我想要验证此文件时,问题开始出现。它返回此异常:
java.security.SignatureException:签名编码错误
位于sun.security.rsa.RSASignature.engineVerify(RSASignature.java:185)
位于java.security.Signature$Delegate.engineVerify(Signature.java:1140)
位于java.security.Signature.verify(Signature.java:592)
位于sun.security.pkcs.SignerInfo.verify(SignerInfo.java:374)
位于sun.security.pkcs.PKCS7.verify(PKCS7.java:494)
位于sun.security.pkcs.PKCS7.verify(PKCS7.java:511)
位于sun.security.pkcs.PKCS7.verify(PKCS7.java:533)
位于firma.firmadigitalipl.firmacadenasun(firmadigitalipl.java:553)
在firma.firmadigitalipl.firmaCardena(firmadigitalipl.java:249)
在firma.firmadigitalipl.firmaCardena(firmadigitalipl.java:147)
位于firma.TestFirma.main(TestFirma.java:75)
原因:java.io.IOException:序列标记错误
位于sun.security.util.DerInputStream.getSequence(DerInputStream.java:280)
位于sun.security.rsa.RSASignature.decodeSignature(RSASignature.java:209)
位于sun.security.rsa.RSASignature.engineVerify(RSASignature.java:174)
... 10多
但问题并不总是出现,只是在使用某种类型的证书进行签名时才会出现。我会解释得更好。
我有两个证书(存储在智能卡中),第一个可以正常工作;我创建了p7s,然后正确验证,但是第二个证书允许我创建p7s文件,但是当我验证它时,它返回SignatureException。我认为p7s文件是错误的,但我用其他人的应用程序测试了它,它看起来是正确的。此外,此文件通过webservice发送,并返回ok
关于更多信息,如果p7s文件是使用不同的工具(.net和capicom)和相同的证书创建的,那么我可以正确验证
我一直在寻找解决办法,但一无所获。我在类似的情况下也发现了同样的异常,但要么建议的解决方案对我不起作用,要么就不出现
如果您能提供任何解决方案,我们将不胜感激。这可能是编码问题:文本与二进制。PKCS7可以是DER编码的二进制格式或PEM格式(即base64编码的DER)。在文本编辑器(如记事本)中打开文件,查看有效的文件是二进制文件还是文本文件。两周多后,我注意到了问题所在,尽管我没有找到完整的解决方案 首先,我从PKCS7文件中提取了问题,并用以下源代码再现了异常:
import diz.firma.keyStore.SmartCard;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
public class TestFirma3 {
public static void main(String args[]) throws Exception {
//Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
SmartCard sm = new SmartCard();
KeyStore ks = sm.loadKeyStore("1234");
//KeyPair keyPair = generateKeyPair(999);
byte[] data = "original".getBytes("UTF-8");
//byte[] data = { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74 };
//byte[] digitalSignature = signData(data, keyPair.getPrivate());
byte[] digitalSignature = signData(data,
(PrivateKey)ks.getKey(sm.getAlias(), null),ks.getProvider());
boolean verified;
//verified = verifySig(data, keyPair.getPublic(), digitalSignature);
verified = verifySig(data, ks.getCertificate(sm.getAlias()).
getPublicKey(),ks.getProvider(), digitalSignature);
System.out.println("verified:" + verified) ;
//keyPair = generateKeyPair(888);
//verified = verifySig(data, keyPair.getPublic(), digitalSignature);
//System.out.println(verified);
}
public static byte[] signData(byte[] data, PrivateKey key,Provider p) throws Exception {
Signature signer = Signature.getInstance("SHA1withRSA",p);
//Signature signer = Signature.getInstance("SHA1withRSA",Security.getProviders()[10]);
signer.initSign(key);
signer.update(data);
return (signer.sign());
}
public static boolean verifySig(byte[] data, PublicKey key, Provider p, byte[] sig) throws Exception {
Signature signer = Signature.getInstance("SHA1withRSA",p);
//Signature signer = Signature.getInstance("SHA1withRSA");
signer.initVerify(key);
signer.update(data);
boolean valido = false;
try{
valido = signer.verify(sig);
}catch(Exception e){
e.printStackTrace();
valido = false;
}
return valido;
}
public static KeyPair generateKeyPair(long seed) throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("DSA");
SecureRandom rng = SecureRandom.getInstance("SHA1PRNG", "SUN");
rng.setSeed(seed);
keyGenerator.initialize(1024, rng);
return (keyGenerator.generateKeyPair());
}
}
在这段代码中(摘自网络中的一个示例),我更改了generators密钥并从我的卡中取出它。我再次遇到异常,没有使用PKCS7文件
查看所有提供程序(使用Security.getProviders()可以获取所有提供程序;它们在java.Security文件中定义,但可以在运行时添加或从中获取),我使用每个人进行签名和验证,我发现:
a) 使用SunMSCAPI提供程序,该提供程序使用Microsoft Crypt API。
b) 由智能卡读卡器创建的供应商,在我的案例中是西门子
因此,我必须找到一个提供者,该提供者在IMB中正确验证SunRsaSign返回SignatureException的签名。我尝试了这两种格式,结果是相同的。如果是问题所在,则不会根据已使用的证书而更改。谢谢你的意见