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.cryptoとjava.security.certの使用法をミルjavaドキュメントの実行よりもよく説明する可能性のあるいくつかのリソースへのリンクを提供できますか?

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 に答える