2009-08-11 14 views
0

Je cherche à convertir du code C# en équivalent Java. Le code C# prend un certain contenu de chaîne, et une signature (générée en utilisant la clé privée, sur une machine séparée) et combiné avec la clé publique, il vérifie la correspondance des signatures, fournissant un niveau d'assurance que la demande n'a pas été altéré.Vérification d'une signature dans java à l'aide d'une clé publique de certificats

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

La clé publique est elle-même un certificat X509 - construit à partir d'un fichier .cer, stocké sous forme de ressources d'assemblage à savoir

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

Ce que je cherche à faire est d'émuler cette fonctionnalité en Java, donc Je peux vérifier la signature générée par un code en C# ... J'ai commencé à étudier la fonctionnalité de chiffrement de Java, mais je suis un peu un java noob. Voici ce que je suis venu avec jusqu'à présent:

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) 

Quelqu'un peut-il fournir une idée de la façon dont je peux vérifier la signature - ou de fournir des liens vers des ressources qui pourraient expliquer la java.crypto et java.security.cert meilleur usage que la course du moulin java docs.

Répondre

2

Ce code C# me semble vraiment confus. Il utilise SHA1CryptoServiceProvider mais utilise le hachage MD5 donc je ne peux pas dire quel algorithme de hachage il utilise. Je suppose que c'est MD5.

Le processus de vérification de signature implique un remplissage afin que votre code ne fonctionne pas. Voici un extrait de mon code et vous pouvez l'utiliser pour vérifier la signature. les données sont les octets à signer et sigBytes détient la signature.

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

Je suis d'accord. La vérification d'une signature est simple en Java, mais ce code C# n'a aucun sens: il devrait y avoir un seul algorithme de hachage impliqué dans la signature. – erickson

+0

Tout à fait d'accord - ce n'est pas du code que j'ai écrit (j'ai récemment adopté la base de code) mais vous avez raison - j'aurais pensé qu'il devrait utiliser MD5 ou SHA1, mais pas les deux! Dans le cas de SHA1, l'algorithme serait-il "SHA1withRSA"? Je vais faire quelques expérimentations et voir quel algorithme le code C# utilise réellement sur les deux. – Bittercoder

+0

Implémenté votre code (et rangé le code C# dans l'application pour n'utiliser que MD5 pour sa signature) et ça fonctionne très bien. Très appréciée! – Bittercoder