我在IIS中创建了一个自签名证书,并将其导出为PFX格式 然后我使用pvkConverter创建了一个Cer文件和一个PVK文件

我使用以下命令在本地数据库中导入这两个文件:

CREATE CERTIFICATE test3   
FROM FILE = 'c:\sql\pvkder.cer'   
    WITH PRIVATE KEY (FILE = 'c:\sql\pvkder.pvk',   
    DECRYPTION BY PASSWORD = '********');  

此导入成功

如果我现在使用signbycert

select SIGNBYCERT(Cert_Id( 'test3' ),'Philip');

结果是:

0x01000502040000006D545003C12AAB0C900B932698CCCD4F117DAE5621EA36CFC63ACF388E44FDEFCCE576286056BA0504DB5D96C1811E5769B21560D4E455F59D3FFBE7CDBD71AC4EE222FC5F6D8960C1EA7649BED4292EE8199C18B01EE5644B8D83FE81F8747FC760E0765BB1FC67933218E7D359F7226E6639B99E6728C507AF05BB68E147627328794A12FDBDCCD30118F4A60F516F9FD29CAF24F64EADAB568523364930A9FE81670D6EF75AD431AC28C169718C36F2F9377B1A0DAF5EA58493AC2CC0342E1C90A9E746C65E8D3535C4AB9D7C364F4FEC2DA3BC691636BA9846D7E6B310FDA665EF16C29A24DDCE6C141610D53B5FE924EE93C6713C875FEB780260EC1888

现在用C#代码编写 我这样做:

string password = "*******";
X509Certificate2 certificate = new X509Certificate2("C:\\SQL\\ChipSoftCertificate.pfx", password);//public X509Certificate2 (string fileName, string? password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags keyStorageFlags);
    
RSA provider = certificate.GetRSAPrivateKey();
var data = Encoding.UTF8.GetBytes("Philip");
var signature = provider.SignData(data, Hash算法rithmName.MD5, RSASignaturePadding.Pkcs1);
var ssignature = Convert.ToHexString(signature);
signature = provider.SignData(data, Hash算法rithmName.SHA1, RSASignaturePadding.Pkcs1);
ssignature = Convert.ToHexString(signature);
signature = provider.SignData(data, Hash算法rithmName.SHA256, RSASignaturePadding.Pkcs1);
ssignature = Convert.ToHexString(signature);
signature = provider.SignData(data, Hash算法rithmName.SHA384, RSASignaturePadding.Pkcs1);
ssignature = Convert.ToHexString(signature);
signature = provider.SignData(data, Hash算法rithmName.SHA512, RSASignaturePadding.Pkcs1);
ssignature = Convert.ToHexString(signature);

则没有一个签名与在SQL服务器上创建的签名相同.

我这样做的原因是,为了安全起见,我最终想用C#代码签署一些东西,并在SQL服务器中验证签名

但现在看来,这种机制并不起作用. 我做错了什么?

问题是,在SQL服务器上的验证与在SQL服务器上创建的符号一起工作 C#代码也是如此.但是我不能使用SQL SERVER和C#的组合

如有任何帮助,我们不胜感激.SQL Server是否使用不同的填充?不同的散列? 有什么办法可以找出答案吗?

select @@VERSION

yield 率

Microsoft SQL Server 2019 (RTM-CU12) (KB5004524) - 15.0.4153.1 (X64)   Jul 19 2021 15:37:34   Copyright (C) 2019 Microsoft Corporation  Express Edition (64-bit) on Windows 10 Enterprise 10.0 <X64> (Build 19045: ) 

推荐答案

不幸的是,SignByCert()的MS文档既没有描述签名的格式,也没有描述算法,所以这必须通过一些测试来解决.

作为测试数据,我使用了以下.pfx数据(Base64编码):

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

和AS消息:

The quick brown fox jumps over the lazy dog

使用该数据,使用SignByCert()生成以下签名:

0x01000502040000004D12072BAF34AC63C9F5FA5035313ED74DA9C3175A30B63D89ED48C0BCA78509C59CED887010B3FFDBBBF7C3257196FDC6AA10D7F7858292BC1A20E46998FB6135FD617FB66C16DCA1ABB5C383BFE293AB0FAFFE410D9B6076BF6A582EAB5C95E8928E5F0CC9ED3B0003D876F03DA210934013901610FC6FAA5C613488D8F53938B305F939A91793022A6C35550A86486D70820BBB51D48B2548B7558AD79BC13C58790796ADB688CA8FBB3077D7D4386A0447DF598F5963814D75F4306C78648C42DD4F175BED38EAF5BB9EB6064206308BB13D7901CE05F4FB0FF301AE5470041CD1C4BD649D49B1E2A629E88EAE3D7D215DFE5E654AD09D73C7DCF0CF8F87

运行以下脚本(例如,请参见here):

CREATE CERTIFICATE MyTestCertificate 
FROM BINARY = 0x3082036B30820253A00302010202146472932AE654353AF660E02361C2062FC040FEE6300D06092A864886F70D01010B05003045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C7464301E170D3233313132303137303835375A170D3234313131393137303835375A3045310B30090603550406130241553113301106035504080C0A536F6D652D53746174653121301F060355040A0C18496E7465726E6574205769646769747320507479204C746430820122300D06092A864886F70D01010105000382010F003082010A0282010100CF9CCF5AF133484FC7DC8FF41C1B9010FC7821B373D0352A57E76A0FA0456AE1F35FDCED60343551594FC0E636727AF868EC237978BBBAE8C366B955A507CB942A3380755F6565F1811BF4476948008F18F3BEBE852540C660A781B362DAD21E70567CE70363EB4DE0F281DB239381308C2A8664B066F7F3331038E62465FC837AF170346AB63D1D18CA0400A6FC41EEE87FEFFB80C01D2FF7B86A1E48F299FA4BECA495C8B33CCB3A9603731AC9CE6B6F55EA1EB91DD919DCCBB17833CB1FB67C97891AF9FAC34EFDB2E7777DF5DFD7E4172638ED65ECBAE08AB5E17EB7EA81937DAAA79F9B041BE3C05488423BB3EF1B26C91D91CF7FD9D7A42E8E5582DA5F0203010001A3533051301D0603551D0E041604145F7A25691BA68CF1D6B59AD50E8F2CA6D0403018301F0603551D230418301680145F7A25691BA68CF1D6B59AD50E8F2CA6D0403018300F0603551D130101FF040530030101FF300D06092A864886F70D01010B0500038201010064E1E3CB35A81CB136B599134D0F536A4D1776CE26B2822B33C415C8E65EE4A8A5E185668455DDF326A4219CAB87D12ED59E85BDA31521201998165F41979CA0DB6608AF2A5D5A3A7566082B6E7B1204666233312E0FFABFF427DDB8E37415559CD8B5405F13425078ACDC1C02AECD3DE372FDC9DE0DCE9A74F3716AF2D0D2ACD06F6070AB620A5E6A5575CA760AED728AAD8549B047345D4F286EA51CB005719B2396F5C0340FB94162EE9E7EAC247CE402169FC754EACAC818C08DAD0A796D336F4437D665CD7ABAB1ED9E30D6213ED2328859709884C35BE1143861429A84FA2CE530F95434554B33131AA66EC6ABC22091E91072242B466877ED6D82C137
WITH PRIVATE KEY ( BINARY = 0x1EF1B5B00000000001000000010000001000000094040000419A89BBB1027ACB5AACB15F8F6AFE370702000000A400009DAD54580C78F832882C12C35E4F44AA9EE8C7EF7A21BB43C39321652366CB79744507A27EF26DA872B8FA1EA9CB4BB67A1C4A819F988BE40162F2C652932DEEF06CD8C1D1DF009F26850407F2C7188D7D4DCB20D34042D4DFC05B60DF7C0046A77528721615F554152612658147DB4F9B8F80A0BEBCAC49B4C7078A40586450B426822AABBD38F2ED938BAE9223CC8EAAC9839448DC5AAC182FB56437EF36D9D492E7B057D1965666884606C99A36BB980DEA611791AD036A7686972736F569A3FE00EFBFE2088C09C1A27A01EC2D0A5D3C3CAB06E30F262BEB377C881F518C7165475A6FB4425FDC301F1EF4A29DB400A335335847EEE3BD3571F63AE8FAA9F6259D346B85B74EEB6AEF7374223E9548ACD7B496B588AFF3AC120A20F04E0F8B44EC5ACAA069671778DE4934224BF2F27AED3F7CFB553E22F843C85E6AE9BC946C9A8768EDD3EE44B08B53977F5B74EBD06110F8A2351CAE69FE4F80AE7E4FF7A9AB472D73E57342C60820D5010D0F7282372D209AA2BDEBD6D14AEF9225F98BFF8E8D237BA588F233CB65C56D57D280067C7B58DEF3B78692B07ED9C182210171B5CEE76DDDF2B441AF302C02E831344F8A56150957FA47DCEE1B7F8CFCAA66DA6D504E22217E7DA33D956AA41ABD92AF455C87BB3FB1032A0D9C08857FD1E6EF5BB1CD7A5958C641E2D723E34BE1A6F6028606BE5DDE3D2A4B89F1D0870E70195CFFEEB70D86C6394068BCB77C7144DE5C8A74BE858E16050C1C9BEF3DE14862FFC83B634675BE3E24F07DEE94FE5881B03AFCFDB82D3A05D2A0BEC96496611E8A02817FA27C4A93482A2B9149F778CFFB1B3BC593B375F304A670D839D136865519A2CA24CE7056DDDC4096CD3089D8CB9A82E971F333C7DE11674264E1A2B7C6E1CB4C75E3E3F62C7FB3E37D628C0358AE12777FB028A6DB66EF48DBD8E14286E6A5A086ABC88ED1C9398EBB2A639A4E8AFB21B000591EC4D45B7BE94FC5AEACDA5FDF9EEDCA1702A57B097B7E577EFCE955BD69C386CC4F8830B2950386B62878CFC8318665F0B02D9524B1BFBFFBDE7AF648E420BC980B38E4445AFC97A66B54E85E831D0EFC2E7B5F822C636A21DB8B28B70134EBA24C98DE0AF683805A9103C51AA9E3FA6C9EC8040AF1C1A6628C5C5C9BA58FA0089A55EB7D2F0121EEB8011485D4F2F479ABABC51AFE98103B4A1BBA090DDE6D18C41F01F5AEA8215D2BCD6F64CF05D451C7DD3DAD4EA8AD136813136AD456289618F829336997E09827CED0AA3F142CF2A1CBEB870020EF34D4465BDB72D93D911AF9DE194990D549E0DDC2DE203C1C6DE2CBC0D2E8FE1835FB2ED2A6CC01B2EDA7050ED0E9FA37251A8876C8A3AB19A6F6802B18E8FE30B4DD1F395F357A5A608BA30E4E39E72CAFB9274589705FF328CE8EA173FD12F188CBD0F6EF3CEA05453E3FB0871138D0F2AEE8C550C8C54D3E992FF88AE7FFE0FCDBD48C5A87A73B0A1984FA50D710A9322304590C294B8A1B7532E4F40A4C802CDAF4E5E053E9D75793319C76A4919F59ED4B40A4C9A42BF0B50536900A75A041305B14AF716984E315AA0A2BD4B40D951DC0B66C64E9935971FFBF4E5BA50940AFB5E7A3A512BD036C8EAA2FFB4B1B83AC9A07D0C51A45EA1BB9 ,
DECRYPTION BY PASSWORD = 'mypassword');

DECLARE @PlainText as varchar(max); 
DECLARE @Signature as varbinary(max); 
SET @PlainText = 'The quick brown fox jumps over the lazy dog';
SET @Signature = SignByCert(Cert_ID('MyTestCertificate'), @PlainText);
SELECT CONVERT([varchar](max), @Signature, 1);

DECLARE @PrivKey as varbinary(max); 
DECLARE @PubKey as varbinary(max); 
SET @PrivKey = CERTPRIVATEKEY(Cert_ID('MyTestCertificate'), 'MyTest!Mast3rP4ss')
SET @PubKey = CERTENCODED(Cert_ID('MyTestCertificate'))
SELECT CONVERT([varchar](max), @PrivKey, 1);
SELECT CONVERT([varchar](max), @PubKey, 1);

签名形式上与您所张贴的签名一致.它的长度为264字节,其中前8个字节是报头,实际签名是最后256个字节.

要验证签名是否使用PKCS#1v1.5填充(更准确地说是使用RSASSA-PKCS1-v1_5)签名,最简单的方法是使用公钥解密签名,因此填充为disabled.此解密确认使用了PKCS#1v1.5填充,但前提是签名4D12...被解释为little endian顺序的签名(请注意,MS通常在数据 struct 中使用低位序,因此这并不奇怪).

在大端顺序中,即在反转之后,签名是十六进制编码的:

878FCFF0DCC7739DD04A655EFE5D217D3DAE8EE829A6E2B1499D64BDC4D11C047054AE01F30FFBF405CE01793DB18B30064206B69EBBF5EA38ED5B174FDD428C64786C30F4754D8163598F59DF47046A38D4D77730BB8FCA88B6AD960779583CC19BD78A55B748258BD451BB0B82706D48860A55356C2A029317A939F905B33839F5D88834615CAA6FFC10169013409310A23DF076D803003BEDC90C5F8E92E8955CAB2E586ABF76609B0D41FEAF0FAB93E2BF83C3B5ABA1DC166CB67F61FD3561FB9869E4201ABC928285F7D710AAC6FD967125C3F7BBDBFFB3107088ED9CC50985A7BCC048ED893DB6305A17C3A94DD73E313550FAF5C963AC34AF2B07124D

或Base64编码:

h4/P8NzHc53QSmVe/l0hfT2ujugppuKxSZ1kvcTRHARwVK4B8w/79AXOAXk9sYswBkIGtp679eo47VsXT91CjGR4bDD0dU2BY1mPWd9HBGo41Nd3MLuPyoi2rZYHeVg8wZvXilW3SCWL1FG7C4JwbUiGClU1bCoCkxepOfkFszg59diINGFcqm/8EBaQE0CTEKI98HbYAwA77ckMX46S6JVcqy5Yar92YJsNQf6vD6uT4r+Dw7WrodwWbLZ/Yf01YfuYaeQgGrySgoX31xCqxv2WcSXD97vb/7MQcIjtnMUJhae8wEjtiT22MFoXw6lN1z4xNVD69cljrDSvKwcSTQ==

然后对解密的签名(带填充)进行十六进制编码(下面的C#代码中的S.test 1):

0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592

这里,最后的字节序列d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592对应于消息的SHA256散列,见here.

这意味着SignByCert()确实not指定了摘要的OID,这与RFC8017, 9.2中描述的PKCS#1v1.5签名的标准相反.因此,使用原生.NET方法SignData()/VerifyData()SignHash()/VerifyHash()进行验证是可能的,因为它们遵循标准并在签名时设置OID,并在验证时将其考虑在内!


另一种 Select 是C#/BouncyCastle,它支持使用NoneWithRSA算法,该算法不散列,因此不设置哈希值.因此,使用SHA 256的散列必须执行explicitly(s).test 2):

using System;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using System.Text;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Math;

...

// key import
byte[] pfx = Convert.FromBase64String("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");
string password = "mypassword";
X509Certificate2 certificate = new X509Certificate2(pfx, password, X509KeyStorageFlags.Exportable);
RSA rsa = certificate.GetRSAPrivateKey();

// test 1: decrypt with public key and padding disabled (i.e. without unpadding)
RSAParameters parameters = rsa.ExportParameters(false);
BigInteger modulusBI = new BigInteger(1, parameters.Modulus);
BigInteger exponentBI = new BigInteger(1, parameters.Exponent);
byte[] signatureSignByCert = Convert.FromHexString("4D12072BAF34AC63C9F5FA5035313ED74DA9C3175A30B63D89ED48C0BCA78509C59CED887010B3FFDBBBF7C3257196FDC6AA10D7F7858292BC1A20E46998FB6135FD617FB66C16DCA1ABB5C383BFE293AB0FAFFE410D9B6076BF6A582EAB5C95E8928E5F0CC9ED3B0003D876F03DA210934013901610FC6FAA5C613488D8F53938B305F939A91793022A6C35550A86486D70820BBB51D48B2548B7558AD79BC13C58790796ADB688CA8FBB3077D7D4386A0447DF598F5963814D75F4306C78648C42DD4F175BED38EAF5BB9EB6064206308BB13D7901CE05F4FB0FF301AE5470041CD1C4BD649D49B1E2A629E88EAE3D7D215DFE5E654AD09D73C7DCF0CF8F87");
Array.Reverse(signatureSignByCert);
BigInteger signatureBI = new BigInteger(1, signatureSignByCert);
BigInteger decryptedBI = signatureBI.ModPow(exponentBI, modulusBI);
Console.WriteLine(Convert.ToHexString(decryptedBI.ToByteArrayUnsigned()).PadLeft(256 * 2, '0')); // 0001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00D7A8FBB307D7809469CA9ABCB0082E4F8D5651E46D3CDB762D02D0BF37C9E592

// test 2: hash message and sign
AsymmetricCipherKeyPair pair = DotNetUtilities.GetRsaKeyPair(rsa);
byte[] digest = SHA256.HashData(Encoding.UTF8.GetBytes("The quick brown fox jumps over the lazy dog"));
ISigner sig = SignerUtilities.GetSigner("NoneWithRSA");
sig.Init(true, pair.Private);
sig.BlockUpdate(digest, 0, digest.Length);
byte[] signature = sig.GenerateSignature();
Console.WriteLine(Convert.ToBase64String(signature)); // h4/P8NzHc53QSmVe/l0hfT2ujugppuKxSZ1kvcTRHARwVK4B8w/79AXOAXk9sYswBkIGtp679eo47VsXT91CjGR4bDD0dU2BY1mPWd9HBGo41Nd3MLuPyoi2rZYHeVg8wZvXilW3SCWL1FG7C4JwbUiGClU1bCoCkxepOfkFszg59diINGFcqm/8EBaQE0CTEKI98HbYAwA77ckMX46S6JVcqy5Yar92YJsNQf6vD6uT4r+Dw7WrodwWbLZ/Yf01YfuYaeQgGrySgoX31xCqxv2WcSXD97vb/7MQcIjtnMUJhae8wEjtiT22MFoXw6lN1z4xNVD69cljrDSvKwcSTQ==

它给出了与SignByCert()相同的签名,正如您预期的那样.


备注:使用SQL Server 2022时,头更改为0100070204000000,使用SHA384作为摘要.

Csharp相关问答推荐

解析需要HttpClient和字符串的服务

使用LayoutKind在C#中嵌套 struct .显式

Unity 2D自顶向下弓旋转

如何在C#中使用正则表达式抓取用逗号分隔的两个单词?

S能够用DATETIME来计算,这有什么错呢?

使用预定义对象减少Task.Run/Factory.StartNew中的关闭开销

单元测试:模拟返回空

EFR32BG22 BLE在SPP模式下与PC(Windows 10)不连接

带有列表参数的表达式树

在C#中过滤Excel文件

对于PowerShell中的ConvertTo-SecureString方法,Microsoft如何将初始化向量添加到AES加密中的安全字符串?

如何在Akka.NET中重新启动执行元时清除邮箱

Azure Functions v4中的Serilog控制台主题

在使用AWS SDK for.NET时,如何判断S3是否已验证我的对象的校验和?

将J数组转换为列表,只保留一个嵌套的JToken

为什么我可以在注册表编辑器中更改值,但不能在以管理员身份运行的C#表单应用程序中更改?

使用C#12中的主构造函数进行空判断

根据优先级整理合同列表

在C#中通过Matheval使用自定义公式

如何在C#中用Serilog记录类路径、方法名和行编号