التحقق من توقيع في Java باستخدام مفتاح الشهادات العامة

StackOverflow https://stackoverflow.com/questions/1258404

سؤال

أتطلع إلى تحويل بعض الكود C # إلى ما يعادل جافا.

يأخذ رمز 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، مخزنة كمورد التجميع IE

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

ما أتطلع إليه هو محاكاة هذه الوظيفة في Java، حتى أتمكن من التحقق من التوقيع الناتج عن بعض الكود في C # ... لقد بدأت التحقيق في وظيفة التشفير في جافا، لكنني قليلا من 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 and java.security.cert بشكل أفضل ثم تشغيل مستندات مطحنة جافا المستندات.

هل كانت مفيدة؟

المحلول

أن C # رمز تبدو مربكة حقا بالنسبة لي. يستخدم sha1cryptoserviceprovider ولكنه يستخدم MD5 Hash حتى لا أستطيع معرفة خوارزمية التجزئة التي تستخدمها. أفترض أنه MD5.

تنطوي عملية التحقق من التوقيع على الحشو حتى لا يعمل الكود الخاص بك. فيما يلي بعض القصاصات من التعليمات البرمجية ويمكنك استخدامها للتحقق من التوقيع. البيانات هي البايتات للتوقيع و 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);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top