0

我希望将一些 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 菜鸟. 到目前为止,这是我想出的:

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.crypto 和 java.security.cert 的用法。

4

1 回答 1

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);
}
于 2009-08-11T06:18:07.877 回答