Механизм CKM_SHA256_RSA_PKCS
делает следующие вещи:
- Вычисляет SHA256-хэш данных точно так же, как
CKM_SHA256
делает
- Создает DER-кодированную
DigestInfo
структуру, определенную в RFC 8017
- Знаки
DigestInfo
структура с закрытым ключом, как CKM_RSA_PKCS
делает
Возможны несколько подходов к построению структуры, закодированной в DER, DigestInfo
:
- В Pkcs11Admin приложении, которое я использовал BouncyCastle Библиотека:
public static byte[] CreateDigestInfo(byte[] hash, string hashOid)
{
DerObjectIdentifier derObjectIdentifier = new DerObjectIdentifier(hashOid);
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(derObjectIdentifier, null);
DigestInfo digestInfo = new DigestInfo(algorithmIdentifier, hash);
return digestInfo.GetDerEncoded();
}
- В Pkcs11Interop.X509Store Библиотека Я использовал предварительно вычисленные массивы:
/// <summary>
/// Creates DER encoded PKCS#1 DigestInfo structure defined in RFC 8017
/// </summary>
/// <param name="hash">Hash value</param>
/// <param name="hashAlgorithm">Hash algorithm</param>
/// <returns>DER encoded PKCS#1 DigestInfo structure or null</returns>
private static byte[] CreatePkcs1DigestInfo(byte[] hash, HashAlgorithmName hashAlgorithm)
{
if (hash == null || hash.Length == 0)
throw new ArgumentNullException(nameof(hash));
byte[] pkcs1DigestInfo = null;
if (hashAlgorithm == HashAlgorithmName.MD5)
{
if (hash.Length != 16)
throw new ArgumentException("Invalid lenght of hash value");
pkcs1DigestInfo = new byte[] { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
}
else if (hashAlgorithm == HashAlgorithmName.SHA1)
{
if (hash.Length != 20)
throw new ArgumentException("Invalid lenght of hash value");
pkcs1DigestInfo = new byte[] { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
}
else if (hashAlgorithm == HashAlgorithmName.SHA256)
{
if (hash.Length != 32)
throw new ArgumentException("Invalid lenght of hash value");
pkcs1DigestInfo = new byte[] { 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
}
else if (hashAlgorithm == HashAlgorithmName.SHA384)
{
if (hash.Length != 48)
throw new ArgumentException("Invalid lenght of hash value");
pkcs1DigestInfo = new byte[] { 0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
}
else if (hashAlgorithm == HashAlgorithmName.SHA512)
{
if (hash.Length != 64)
throw new ArgumentException("Invalid lenght of hash value");
pkcs1DigestInfo = new byte[] { 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
}
return pkcs1DigestInfo;
}