我希望将一些C#代码转换为Java中的等价代码。
C#代码采用一些字符串内容和签名(使用私钥在单独的机器上生成)并与公钥结合使用,验证签名匹配,从而提供一定程度的保证请求未被篡改用。
public bool VerifySignature(string content, byte[] signatureBytes, AsymmetricAlgorithm publicKey)
{
var hash = new MD5CryptoServiceProvider();
byte[] dataBuffer = Encoding.ASCII.GetBytes(content);
var cs = new CryptoStream(Stream.Null, hash, CryptoStreamMode.Write);
cs.Write(dataBuffer, 0, dataBuffer.Length);
cs.Close();
var deformatter = new RSAPKCS1SignatureDeformatter(publicKey);
deformatter.SetHashAlgorithm("MD5");
return deformatter.VerifySignature(hash, signatureBytes);
}
公钥本身是一个X509证书 - 由.cer文件构建,存储为汇编资源,即
byte[] data; // data is read from a resource stream.
var publicKey = new X509Certificate2(data, "", X509KeyStorageFlags.MachineKeySet).PublicKey.Key
我想要做的是用Java模拟这个功能,所以我可以验证C#中某些代码生成的签名...我已经开始调查Java的加密功能了,但我有点像一个java noob。这是我到目前为止所提出的:
byte[] certContents=null;
byte[] signature=null;
String contents = "abc";
// load cert
CertificateFactory factory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(certContents));
// grab public key
RSAPublicKey publicKey = (RSAPublicKey)cert.getPublicKey();
// get sha1 hash for contents
Mac mac = Mac.getInstance("HmacSHA1");
mac.update(contents.getBytes());
byte[] hash = mac.doFinal();
// get cipher
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
// verify signature of contents matches signature passed to method somehow (and this is where I'm stuck)
任何人都可以提供有关我如何验证签名的任何见解 - 或提供一些资源的链接,这些资源可能比java java文档的运行更能解释java.crypto和java.security.cert的用法。
答案 0 :(得分:2)
C#代码对我来说真的很混乱。它使用SHA1CryptoServiceProvider但使用MD5哈希,所以我不知道它正在使用哪种哈希算法。我认为它是MD5。
签名验证过程涉及填充,因此您的代码无效。以下是我的代码中的一些代码段,您可以使用它来验证签名。 data是要签名的字节,sigBytes包含签名。
String algorithm = "MD5withRSA";
// Initialize JCE provider
Signature verifier = Signature.getInstance(algorithm);
// Do the verification
boolean result=false;
try {
verifier.initVerify(cert); // This one checks key usage in the cert
verifier.update(data);
result = verifier.verify(sigBytes);
}
catch (Exception e) {
throw new VerificationException("Verification error: "+e, e);
}