c# - 使用 SoftHSM 2.2.0(带有 SHA256 的 ECDSA)C#.net 从 Pkcs11Interop 为 CKM_ECDSA_SHA256 签名 PDF

标签 c# pkcs#11 ecdsa softhsm pkcs11interop

我正在尝试使用 Pkcs11Interop .net 库对 Pdf 文档进行签名。 我需要使用 ECDSA 加密 算法和 SHA256 哈希算法。 我正在使用 SoftHSM 2.2.0 来存储私钥。

我发现了一个 CKM 枚举,CKM_ECDSA_SHA256,我在创建用于调用 Session 的 Sign 方法的类机制对象时传递了它。

我从“Signdata”方法得到响应,但是,在打开签名后生成的 Pdf 文件时给出错误“Signature Invalid”。 下面是 Signdata 方法调用的代码片段。 我在代码中没有收到任何错误或异常,但是,我提到的 pdf 显示签名无效。

private Pkcs11 _pkcs11;
private Slot _slot;
private Session _session;

try
{
   _pkcs11 = new Pkcs11(hsmCryptoApi, true);
}
catch (Pkcs11Exception ex)
{
   if (ex.RV == CKR.CKR_CANT_LOCK)
      _pkcs11 = new Pkcs11(hsmCryptoApi, false);
   else
       throw ex;
}

_slot = FindSlot(_pkcs11, _certificateInformation.TokenLabel);
_session = _slot.OpenSession(true);

using (Mechanism mechanism = new Mechanism(CKM.CKM_ECDSA_SHA256))
{
  _session.Login(CKU.CKU_USER, passowrd);
  byte[] signedHash = _session.Sign(mechanism, GetPrivateKeyHandle(), message);
  _session.Logout();
  return signedHash;
}

private ObjectHandle GetPrivateKeyHandle()
{
  string keyLabel = _certificateInformation.KeyLabel;
  List<ObjectAttribute> searchTemplate = new List<ObjectAttribute>();
  searchTemplate.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
  searchTemplate.Add(new ObjectAttribute(CKA.CKA_LABEL, keyLabel));
  List<ObjectHandle> foundObjects = _session.FindAllObjects(searchTemplate);
  return foundObjects[0]; 
}
  • 请告诉我 SoftHSM 2.2.0 是否支持带 SHA256 的 ECDSA_P256??
  • 如果没有,那么有什么方法可以启用支持吗??
  • 如果确实支持,请帮我解决这个问题??
  • 看起来它想让我传递 ECDSA_Param,有没有人有传递 ECDSA_Param 的代码片段

最佳答案

我认为您需要构造 ECDSA-Sig-Value 结构并用您的 signedHash 变量中的数据填充它。

PKCS#11 v2.20第 12.3.1 章:

For the purposes of these mechanisms, an ECDSA signature is an octet string of even length which is at most two times nLen octets, where nLen is the length in octets of the base point order n. The signature octets correspond to the concatenation of the ECDSA values r and s, both represented as an octet string of equal length of at most nLen with the most significant byte first. If r and s have different octet length, the shorter of both must be padded with leading zero octets such that both have the same octet length. Loosely spoken, the first half of the signature is r and the second half is s. For signatures created by a token, the resulting signature is always of length 2nLen. For signatures passed to a token for verification, the signature may have a shorter length but must be composed as specified before.

RFC5753第 7.2 章:

When using ECDSA with SignedData, ECDSA signatures are encoded using the type:

ECDSA-Sig-Value ::= SEQUENCE {
    r INTEGER,
    s INTEGER }

ECDSA-Sig-Value is specified in [PKI-ALG]. Within CMS, ECDSA-Sig-Value is DER-encoded and placed within a signature field of SignedData.

以下方法使用BouncyCastle构建 DER 编码的 ECDSA-Sig-Value 结构的库:

public static byte[] ConstructEcdsaSigValue(byte[] rs)
{
    if (rs == null)
        throw new ArgumentNullException(nameof(rs));

    if (rs.Length < 2 || rs.Length % 2 != 0)
        throw new ArgumentException("Invalid length", nameof(rs));

    int halfLen = rs.Length / 2;

    byte[] half1 = new byte[halfLen];
    Array.Copy(rs, 0, half1, 0, halfLen);
    var r = new Org.BouncyCastle.Math.BigInteger(1, half1);

    byte[] half2 = new byte[halfLen];
    Array.Copy(rs, halfLen, half2, 0, halfLen);
    var s = new Org.BouncyCastle.Math.BigInteger(1, half2);

    var derSequence = new Org.BouncyCastle.Asn1.DerSequence(
        new Org.BouncyCastle.Asn1.DerInteger(r),
        new Org.BouncyCastle.Asn1.DerInteger(s));

    return derSequence.GetDerEncoded();
}

关于c# - 使用 SoftHSM 2.2.0(带有 SHA256 的 ECDSA)C#.net 从 Pkcs11Interop 为 CKM_ECDSA_SHA256 签名 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44010018/

相关文章:

c# - 在 C# 中的存储过程中使用全局临时表

encryption - KMIP 和 PKCS#11 有什么关系?

java - 列出 Java 中的所有智能卡插槽

带有 SHAwithECDSA 的 Java Signature.sign() 在多次运行时产生不同的结果

c# - 读取具有多个具有相同名称的类的子控件的子控件?

c# - 如果未检测到换行符,则服务器的套接字阻塞,但未检测到客户端的套接字

c# - 进程启动但不显示窗口

encryption - 使用 openssl 封装 PKCS11 key

php - 用于 Apple AppStoreConenct API Auth 的 ES256 JWT 登录 PHP

openssl - 如何将ECDSA key 转换为PEM格式