Java Digital Signature different to C#

2019-02-10 12:09发布

I have the following c# code to generate a digital signature from a private key:

    static string Sign(string text, string certificate)
    {

        X509Certificate2 cert = new X509Certificate2(certificate, "TestPassword", X509KeyStorageFlags.Exportable);
        RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
        // Hash the data
        SHA1Managed sha1 = new SHA1Managed();
        ASCIIEncoding encoding = new ASCIIEncoding();
        byte[] data = encoding.GetBytes(text);
        byte[] hash = sha1.ComputeHash(data);
        // Sign the hash
        return System.Convert.ToBase64String(rsa.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")));            
    }

I then created what I thought was the equivalent java code:

public static String signData(String dataToSign, String keyFile) { 
  FileInputStream keyfis = null;
  try {
    keyfis = new FileInputStream(fileName);
    KeyStore store = KeyStore.getInstance("PKCS12");
    store.load(keyfis, "TestPassword".toCharArray());
    KeyStore.PrivateKeyEntry pvk = (KeyStore.PrivateKeyEntry)store.
          getEntry("testkey", 
          new KeyStore.PasswordProtection("TestPassword".toCharArray()));
    PrivateKey privateKey = (PrivateKey)pvk.getPrivateKey();
    byte[] data = dataToSign.getBytes("US-ASCII");
    MessageDigest md = MessageDigest.getInstance("SHA1");
    byte[] hashed = md.digest(data);
    Signature rsa = Signature.getInstance("SHA1withRSA");
    rsa.initSign(privateKey);
    rsa.update(data);
    return Base64.encode(rsa.sign());
  } catch (Exception ex) {
    Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
  } finally {
    if ( keyfis != null ) {
      try { keyfis.close() } catch (Exception ex) { keyfis = null; }
    }
  }
  return null;
}

Unfortunately the digital signatures do not match.

Any assistance will be greatly appreciated. Thanks in advance.

EDIT: If I remove the MessageDigest from the java code then the output is the same. Why? I thought hashing is needed.

Regards, Eugene

2条回答
贼婆χ
2楼-- · 2019-02-10 12:33

The Java sign method does hashing and signing based on the algorithms provided in getInstance method of the Signature class, so basically you were hashing twice in Java.

查看更多
Luminary・发光体
3楼-- · 2019-02-10 12:39

Ok so I have confirmed it. If I remove the MessageDigest/Hashing code from the java sample code then the two digital signatures are the same. Not sure why, but I'll try and find out. If anyone would like to educate me further feel free.

查看更多
登录 后发表回答