2009-08-11 10 views
0

私は、Javaで同等の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証明書である - すなわち

byte[] data; // data is read from a resource stream. 
var publicKey = new X509Certificate2(data, "", X509KeyStorageFlags.MachineKeySet).PublicKey.Key 

アセンブリリソースとして保存され、.cerファイルから構築された私はしているよ何ので、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.cryptoとjava.security.certのを説明するかもしれないいくつかのリソースへのリンクを提供より良い使用して、ミルのJavaドキュメントの実行。

答えて

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); 
} 
+1

私は同意します。 Javaでシグネチャを確認するのは簡単ですが、C#コードは意味をなさない:シグネチャに含まれる単一のハッシュアルゴリズムが必要です。 – erickson

+0

完全に合意しました - 私が書いたコードではありませんが(最近はコードベースを採用したばかりです)、あなたが正しいです。私はMD5またはSHA1のどちらかを使用するべきだと思っていましたが、 SHA1の場合、アルゴリズムは「SHA1withRSA」ですか? 私はいくつかの実験を行い、C#コードが2つのアルゴリズムのうち実際に使用しているアルゴリズムを確認します。 – Bittercoder

+0

あなたのコードを実装しました(そして、アプリケーションでC#コードを整理してMD5のみを署名として使用しています)。とても有難い! – Bittercoder

関連する問題