我正在基于 .net 的智能卡上签署一些数据,并尝试在 java 环境中验证该签名 - 但没有成功。
智能卡(c#):
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024);
// In a different method, rsaParams.Exponent and rsaParams.Modulus are set
rsaProvider.ImportParameters(rsaParams); // Here I'm importing the key
SHA1 sha1 = SHA1.Create();
byte[] signature = rsaProvider.SignData(data, sha1);
客户端(Java):
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(rsaPublicKey); // initiate the signature with public key
sig.update(data); // update signature with the data that was signed by the card
sig.verify(signedData); // Test card signature - this always returns false
然后,我尝试在 Java 客户端上创建签名(用于测试)——结果发现在 Java 客户端上创建的签名与在智能卡上创建的签名不同。我这样创建它:
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign(rsaPrivateKey);
sig.update(data);
locallySigned = sig.sign();
现在我明白签名类似于(传递的数据+使用的算法)的哈希值。这里的实现是否可能不兼容?我还缺少其他东西吗?谢谢!
PS:是的,我验证了输入和输出都正确地从卡传输到卡,关键参数已设置并且输入/输出完全相同。
编辑: Java 中的密钥生成:
// Create a key-pair and install the private key on the card
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);
KeyPair keyPair = keyGen.genKeyPair();
privateKey = (RSAPrivateKey)keyPair.getPrivate();
publicKey = (RSAPublicKey)keyPair.getPublic();
然后我在卡上设置私钥的 exp 和 mod。