当前位置: 首页 > 知识库问答 >
问题:

创建RSA-SHA1签名

韦思淼
2023-03-14

是否可以使用存储在Azure密钥库中的X509证书创建RSA-SHA1签名?“不可抵赖证明书”

不幸的是,我不能将哈希算法更改为SHA256或更安全的东西,我真的需要将证书作为密钥存储在Azure Key Vault中。

await kvClient.SignAsync(keyVaultUrl, "RSNULL", digest); // digest = 20byte SHA1
await kvClient.SignAsync(keyVaultUrl, "RSNULL", ans1Digest); // asn1Digest = 35byte SHA1 wrapped in ANS1 structure
    null

共有1个答案

华景焕
2023-03-14

我盲目拍摄的“专业”意见是,您没有正确构建PKCS#1 DigestInfo结构。下面的控制台应用程序对我来说使用SHA1和SHA256算法都很好(没有测试其他算法):

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.KeyVault;
using Microsoft.IdentityModel.Clients.ActiveDirectory;

namespace AzureKeyVaultTestApp1
{
    static class Program
    {
        static HashAlgorithmName _hashAlg = HashAlgorithmName.SHA1;
        static string _clientId = "00000000-0000-0000-0000-000000000000";
        static string _clientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        static string _certId = "https://XXXXXXXX.vault.azure.net/certificates/TestCert1/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        static string _keyId = "https://XXXXXXXX.vault.azure.net/keys/TestCert1/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

        static async Task<string> AuthenticationCallback(string authority, string resource, string scope)
        {
            var context = new AuthenticationContext(authority);
            var result = await context.AcquireTokenAsync(resource, new ClientCredential(_clientId, _clientSecret));
            return result.AccessToken;
        }

        static async Task Main(string[] args)
        {
            KeyVaultClient client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(AuthenticationCallback));

            // Compute digest of data
            byte[] dataToSign = Encoding.ASCII.GetBytes("Hello world!");
            byte[] hash = HashAlgorithm.Create(_hashAlg.Name).ComputeHash(dataToSign);

            // Construct DER encoded PKCS#1 DigestInfo structure defined in RFC 8017
            byte[] pkcs1DigestInfo = CreatePkcs1DigestInfo(hash, _hashAlg);

            // Sign digest with private key
            var keyOperationResult = await client.SignAsync(_keyId, "RSNULL", pkcs1DigestInfo).ConfigureAwait(false);
            byte[] signature = keyOperationResult.Result;

            // Get public key from certificate
            var certBundle = await client.GetCertificateAsync(_certId).ConfigureAwait(false);
            X509Certificate2 cert = new X509Certificate2(certBundle.Cer);
            RSA rsaPubKey = cert.GetRSAPublicKey();

            // Verify digest signature with public key
            if (!rsaPubKey.VerifyHash(hash, signature, _hashAlg, RSASignaturePadding.Pkcs1))
                throw new Exception("Invalid signature");
        }

        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;
        }
    }
}
 类似资料:
  • 问题内容: 我有一个字符串,一个签名和一个公共密钥,我想验证字符串上的签名。密钥如下所示: 我已经阅读了一段时间的pycrypto文档,但是我不知道如何使用这种密钥制作RSAobj。如果您了解PHP,我将尝试执行以下操作: 另外,如果我对任何术语感到困惑,请告诉我。 问题答案: 标记之间的数据是包含PKCS#1 RSAPublicKey的PKCS#8 PublicKeyInfo的ASN.1 DER

  • 问题内容: 我正在尝试在python3上创建一个非分离签名。我目前有使用m2crypto在python2上执行此操作的代码,但是m2crypto无法用于python3。 我一直在尝试rsa,pycrypto和openssl,但尚未找到找到方法。 这是等效的OpenSSL命令: 这是我无法使用rsa,pyopenssl或pycrypto模仿的选项。 有人在python3上这样做吗?我想尽可能避免使用

  • 在本章中,我们将重点介绍使用Python逐步实现RSA算法。 生成RSA密钥 生成RSA密钥涉及以下步骤 - 创建两个大素数,即p和q 。 这些数字的乘积称为n ,其中n= p*q 生成与(p-1)和(q-1).相对素数的随机数(q-1). 将数字称为e 。 计算e的模逆。 计算的倒数将被称为d 。 生成RSA密钥的算法 我们需要两个使用Python生成RSA密钥的主要算法 - Cryptomat

  • 我需要使用RSA-SHA1算法对XML文档的一个节点进行签名(并最终验证)。W3.org链接 RSA-SHA1 URI: http://www.w3.org/2000/09/XMLDSIG#RSA-SHA1 指定于: [XMLDSIG-CORE2002]第6.4.2节 签名生成发生在以下位置: 唯一带有参数的重写需要: (链接) 在.NET中用RSA-SHA1签署XML最轻松的方式是什么? 编辑:

  • 我在创建/使用在PHP中创建和使用的RSA密钥方面有一个问题。问题是,(公共和私人)密钥应该在不同的服务器之间交换(例如,当移动用户帐户时)。 现在,PHP的openssl库没有提供任何关于密钥创建格式的详细信息。最新文档位于http://php.net/manual/en/function.openssl-pkey-export.php只是声明它是“PEM格式”,但没有说明它是在PKCS#1还是

  • 我们有一个java程序,它使用私钥对xml文件进行签名,如下所示: 现在,我必须验证这个签名在C使用cryptocpp。我所尝试的: 我验证了作为xmlString传递的数据与用于在java中创建签名的数据是二进制的。签名是base64编码的,我也尝试使用它进行解码。到目前为止,我总是失败。 如果我使用cryptopp创建带有私钥的签名,那么验证创建的签名就不会有问题。 这里可能有什么问题?我确信