当前位置: 首页 > 面试题库 >

Java数字签名不同于C#

谭骏
2023-03-14
问题内容

我有以下c#代码从私钥生成数字签名:

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

然后,我创建了我认为等效的Java代码:

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

不幸的是,数字签名不匹配。

任何帮助将不胜感激。提前致谢。

编辑 :如果我从Java代码中删除MessageDigest,则输出是相同的。为什么?我以为需要哈希。

问候,尤金


问题答案:

Java sign方法基于Signature类的getInstance方法提供的算法进行哈希和签名,因此基本上您在Java中进行了两次哈希。



 类似资料:
  • 第二个是不同的,我必须手动添加属性,但是生成的PDF已损坏(然后我可能需要添加发行人序列属性): 有没有人懂使用java的CAdES数字签名?任何帮助都将不胜感激!

  • 数字签名 类似在纸质合同上签名确认合同内容,数字签名用于证实某数字内容的完整性(integrity)和来源(或不可抵赖,non-repudiation)。 一个典型的场景是,A 要发给 B 一个文件(一份信息),B 如何获知所得到的文件即为 A 发出的原始版本?A 先对文件进行摘要,然后用自己的私钥进行加密,将文件和加密串都发给 B。B 收到后文件和加密串,用 A 的公钥来解密加密串,得到原始的数

  • 我一直在网络和java教程中寻找这一点。但我没有澄清如何为文档生成数字签名。java教程对此进行了解释,但我真正想要的是 用户附带一个文件和一个字符串密钥 使用该密钥,文件被数字签名 相应的公钥,该标志与该文档一起发布 那么,如何转换给定的String私钥来做到这一点。在尝试java教程和web中给出的示例(带有将字节从字符串而不是文件中放置的一些变体)时,我遇到了如下异常

  • 我已经阅读了I-TEXT数字签名电子文本,以及MKL(他似乎和布鲁诺一起是这个主题的权威)回答的以前的帖子。 本质上,我有一个Azure应用程序服务,它从公司的签名API获得数字签名(基础64)和证书链。该公司的签名API在Base64中返回签名以及证书链。 我只想在pdf中插入一个签名对象/容器,这样当最终用户打开pdf时,它就会显示在签名面板中。我更喜欢使用延期签名。 可悲的是,事情不能工作,

  • 我想用PHP实现一个XML数字签名。我正在这个验证器上测试签名的正确性。 我得到了错误的签名值,所以我要一步一步地解释我在做什么,请纠正我做错了什么。 我要签名的XML(无新行): 首先,我规范化XML,然后使用sha256对其进行散列,从而生成正确的摘要值。 第二,创建SignedInfo XML元素并规范化它(无新行): 最后,使用RSA-SHA256对SignedInfo元素进行签名。这是产

  • 为了在我们的JUnit测试中使用H2数据库而不是调用Oracle,我被阻止在H2上创建别名以模拟一些Oracle兼容性: > 我首先为日期到字符的转换声明了to_char的别名:可以