Разные подписи при подписании одних и тех же данных с использованием одного и того же закрытого ключа в Pkcs11Interop и C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Разные подписи при подписании одних и тех же данных с использованием одного и того же закрытого ключа в Pkcs11Interop и

Сообщение Anonymous »

Я хочу использовать аппаратный модуль безопасности (HSM) для подписи строки. В частности, я использую для этого ePass3003Auto. Я сохранил сертификат в HSM, у которого есть закрытый ключ. Используя пакет Pkcs11Interop и механизм CKM.CKM_SHA256_RSA_PKCS, я получаю результат X. Чтобы проверить точность процесса подписи, я также использую RSACryptoServiceProvider для подписи тех же данных с использованием аргументов HashAlgorithmName.SHA256 и RSASignaturePadding.Pkcs1, что дает результат Y .
Что я уже сделал?
  • Я проверил закрытый ключ и подтвердил, что ключ, используемый в RSACryptoServiceProvider, идентичен ключу, хранящемуся в HSM. Чтобы еще больше убедиться в этом, я протестировал оба метода с использованием SHA1 и получил одинаковые подписи, что указывает на то, что ключи действительно одинаковы.
  • Я проверил, что данные передаются в оба метода. алгоритмы идентичны, и проблема не в кодировании. Массивы байтов, передаваемые методам подписи, также одинаковы.
  • Я пробовал конфигурации x86 и x64, но только в качестве HSM имеет одну библиотеку и нет отдельной библиотеки для разных архитектур, разницы в результатах не было.
  • Для проверки результата подписания тех же данных с помощью HSM я использовал другую программу, которая также дал результат Y. Таким образом, похоже, что RSACryptoServiceProvider генерирует правильную подпись, а мой подход с использованием Pkcs11Interop неверен.
Вот упрощенная версия моего кода:
using Net.Pkcs11Interop.Common;
using Net.Pkcs11Interop.HighLevelAPI;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace TestSigningProblem
{
internal class Program
{
internal static string SignUsingHSM(string data, string tokenId, string pin)
{
const string modulePath = @"C:\Windows\System32\ShuttleCsp11_3003.dll";
var factories = new Pkcs11InteropFactories();

using (var pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, modulePath, AppType.MultiThreaded))
{
// Find first slot with token present
var slot = pkcs11Library.GetSlotList(SlotsType.WithOrWithoutTokenPresent).First();

// Open RW session
using (var session = slot.OpenSession(SessionType.ReadWrite))
{
// Login as normal user
session.Login(CKU.CKU_USER, pin);

// Specify signing mechanism
var mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_SHA256_RSA_PKCS);

var sourceData = Encoding.UTF8.GetBytes(data);

var pkcs11UriBuilder = new Pkcs11UriBuilder
{
ModulePath = modulePath,
PinValue = pin,
Type = CKO.CKO_PRIVATE_KEY
};

var searchTemplate = Pkcs11UriUtils.GetObjectAttributes(new Pkcs11Uri(pkcs11UriBuilder.ToString()), session.Factories.ObjectAttributeFactory);
var allObjects = session.FindAllObjects(searchTemplate);
var foundObject = allObjects.FirstOrDefault(x => session.GetAttributeValue(x, new List() { CKA.CKA_ID }).First().GetValueAsString().StartsWith(tokenId, StringComparison.OrdinalIgnoreCase));
if (foundObject == null)
{
throw new Exception("Certificate not found");
}

// Sign data
var signature = session.Sign(mechanism, foundObject, sourceData);

session.Logout();

return ConvertUtils.BytesToBase64String(signature);
}
}
}

internal static string SignUsingPrivateKey(string data, string privateKey)
{
var pem = $"-----BEGIN PRIVATE KEY-----\n{privateKey}\n-----END PRIVATE KEY-----"; // Add header and footer
var pemReader = new PemReader(new StringReader(pem));
var rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)pemReader.ReadObject());
var cryptoServiceProvider = new RSACryptoServiceProvider();
cryptoServiceProvider.ImportParameters(rsaParams);
var dataBytes = Encoding.UTF8.GetBytes(data);
return Convert.ToBase64String(cryptoServiceProvider.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
}

static void Main(string[] args)
{
var data = "T";
var privateKey = File.ReadAllText(@"private.key");
Console.WriteLine(SignUsingHSM(data, "********************************", "********"));
Console.WriteLine(SignUsingPrivateKey(data, privateKey));
Console.ReadKey();
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/785 ... -key-in-pk
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»