[英]Pkcs11Interop (C#) - Calculate HMAC Signature on Utimaco HSM Simulator
[英]How to create Digital Signature with CAdES format using Pkcs11Interop in C# without data or document to sign
我是密码编程的新手。 我只想使用 Pkcs11Interop 库在 C# 中创建带有 CAdES 格式的数字签名,而没有要签名的数据或文档或消息,我希望签名字符串仅在从我的应用程序生成的任何 json 或 xml 文件上使用它。 我使用 Pkcs11Interop 库是因为我有一个带有非托管 PKCS#11 dll 库的智能令牌“Cryptoki”,我必须使用它来制作签名。 这是我基于 Pkcs11Interop 开源示例的示例代码。
using System;
using System.Collections.Generic;
using Net.Pkcs11Interop.Common;
using Net.Pkcs11Interop.HighLevelAPI;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Pkcs11InteropFactories factories = new Pkcs11InteropFactories();
using (IPkcs11Library pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, @"C:\eps2003csp11.dll", AppType.MultiThreaded))
{
ILibraryInfo libraryInfo = pkcs11Library.GetInfo();
foreach (ISlot slot in pkcs11Library.GetSlotList(SlotsType.WithOrWithoutTokenPresent))
{
ISlotInfo slotInfo = slot.GetSlotInfo();
if (slotInfo.SlotFlags.TokenPresent)
{
using (ISession session = slot.OpenSession(SessionType.ReadWrite))
{
session.Login(CKU.CKU_USER, @"000000");
IObjectHandle publicKey = null;
IObjectHandle privateKey = null;
GenerateKeyPair(session, out publicKey, out privateKey);
IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_CMS_SIG);
byte[] sourceData = ConvertUtils.Utf8StringToBytes(null);
byte[] signature = session.Sign(mechanism, privateKey, sourceData);
string vStringSignature = ConvertUtils.BytesToBase64String(signature);
Console.WriteLine("Signature: " + vStringSignature);
session.DestroyObject(privateKey);
session.DestroyObject(publicKey);
session.Logout();
}
}
}
}
}
static void GenerateKeyPair(ISession session, out IObjectHandle publicKeyHandle, out IObjectHandle privateKeyHandle)
{
// The CKA_ID attribute is intended as a means of distinguishing multiple key pairs held by the same subject
byte[] ckaId = session.GenerateRandom(20);
// Prepare attribute template of new public key
List<IObjectAttribute> publicKeyAttributes = new List<IObjectAttribute>();
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PRIVATE, false));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_LABEL, "Digital Business ERP"));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ID, ckaId));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ENCRYPT, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_VERIFY, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_VERIFY_RECOVER, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_WRAP, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_MODULUS_BITS, 1024));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PUBLIC_EXPONENT, new byte[] { 0x01, 0x00, 0x01 }));
// Prepare attribute template of new private key
List<IObjectAttribute> privateKeyAttributes = new List<IObjectAttribute>();
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PRIVATE, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_LABEL, "Digital Business ERP"));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ID, ckaId));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SENSITIVE, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_DECRYPT, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SIGN, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SIGN_RECOVER, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_UNWRAP, true));
// Specify key generation mechanism
IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_RSA_PKCS_KEY_PAIR_GEN);
// Generate key pair
session.GenerateKeyPair(mechanism, publicKeyAttributes, privateKeyAttributes, out publicKeyHandle, out privateKeyHandle);
}
}
}
如果我将“null”或空双引号放在以下 sourceData 变量中
byte[] sourceData = ConvertUtils.Utf8StringToBytes(null);
或者
byte[] sourceData = ConvertUtils.Utf8StringToBytes("");
我在创建这样的签名时出错
byte[] signature = session.Sign(mechanism, privateKey, sourceData);
或者
byte[] signature = session.Sign(mechanism, privateKey, null);
仅当我放入“Hello World”等示例数据时,签名字符串才会成功生成,但它包含此示例中的“Hello World”数据字符串。
我想生成不包含任何数据的签名字符串,同样在我的代码中,我不知道如何将签名格式设置为 CAdES。
塔雷克
我也在为同样的问题苦苦挣扎,试图在 json 文档上生成 cades-bes 签名并将其作为属性附加到原始 json 文档。
这是埃及税务机关使用其 Api 提交已签名发票的规则的一部分。
我试过CMS类的。 Net core,并设法生成了文档的签名,但 Api 拒绝了我的文档,我收到了 400“错误请求”的响应。
如果您在 eduvor 中管理,请在此处添加解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.