2011-08-10 4 views
0

J'ai un exemple de code en Java que j'essaie de convertir en plate-forme .NET C#. Ce code crypte une chaîne et y ajoute une signature. Le code Java utilisant le fournisseur BouncyCastle et le code pour l'ajout de la signature sont les suivants..NET et Java produisant une signature différente

InputStream in = new FileInputStream(derkeyfilename); 
byte[] privKeyBytes = new byte[in.available()]; 
in.read(privKeyBytes); 
KeyFactory rsaKeyFac = KeyFactory.getInstance("RSA"); 
PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(privKeyBytes); 
private RSAPrivateKey myPrivateKey = (RSAPrivateKey) rsaKeyFac.generatePrivate(encodedKeySpec); 

MessageDigest md = MessageDigest.getInstance("MD5", "BC"); 
byte[] digest = md.digest(msg); 
Signature sig = Signature.getInstance("MD5withRSA", "BC"); 
sig.initSign(myPrivateKey); 
sig.update(digest); 
byte[] signature = sig.sign(); 
byte[] base64 = Base64.encodeBase64(signature); 
String signature = new String(base64); 

Quelqu'un peut-il m'aider à convertir ceci en C#. J'ai essayé quelques samples (BouncyCastle pour C#, openssl etc) et tous retournent la même signature qui est différente de ce que java produit. Une autre chose que j'ai trouvée est que java utilise la clé privée .der qui n'est pas supportée en C# (pour autant que je sache). J'utilise la clé .pem pour le même certificat.

+2

Votre façon de lire à partir d'un InputStream est cassée pour commencer. Personnellement, je ne fais jamais confiance à 'available()' et vous ne devriez jamais lire à partir d'un flux et ignorer la valeur de retour de 'read'. Avez-vous vérifié si les résumés sont les mêmes? Comment obtenez-vous les octets de la chaîne pour commencer? Un exemple court mais * complet * serait vraiment utile - y compris ce que vous avez essayé en C#. Si plusieurs approches .NET donnent la même signature, c'est probablement la bonne ... –

+0

De plus, vous fournissez * seulement * le 'Signature' avec le résumé MD5 ... ne devriez-vous pas le fournir avec l'entrée données ('msg')? –

+0

@Jon digests sont toujours signés, pas les données complètes. –

Répondre

2

Comme vous ne vous présentez pas votre C# moment, je ne peux que deviner ce que votre problème est:

En Java, vous êtes en train de faire un double hachage MD5. Une fois explicitement dans votre code, et une fois implicitement dans votre objet Signature (qui est défini comme MD5WithRSA, comme vous pouvez le voir). Ainsi, vous avez ici

signatureJava = RSA(MD5(MD5(msg))) 

Si vous ne faites pas ce premier MD5 explicitement sur le côté C#, vous y avez:

signatureC# = RSA(MD5(msg)) 

Il est évident que ce ne sont pas les mêmes, sauf si vous avez atteint un point fixe de MD5 avec votre message (très peu probable).

À part cela, êtes-vous sûr que la signature C# est toujours la même? Si je comprends bien, une signature RSA est (in the modes normally used) non déterministe, car elle intègre certaines données de remplissage aléatoire.

+0

+1 Malheureusement, PSS n'est pas le mode normal en Java, c'est toujours RSA avec un remplissage PKCS # 1.5. – emboss

Questions connexes