在数据库中存储X509Certificate2

7

是否可以将X509Certificate2存储在SQL Server表中,而不是从文件系统中获取.p12文件?我相信可以实现,但不确定如何操作。

2个回答

11
这是完全可能的,X509Certificate2有一个RawData属性,可以保存到您的SQL数据库中。要重建证书,您可以使用此constructor
var cert = new X509Certificate2(filename);
var data = cert.RawData;

// save data to database...

// Fetch data from database...

cert = new X509Certificate2(data);

那么你仍然需要将 .p12 流读入一个对象,然后存储,对吗?我不能只是打开 p12 文件,复制其内容并将其扔进名为 Certificates 的表中的 varchar 字段中,此后再也不必从物理文件中读取了吧?也许我太天真了。 - PositiveGuy
好的,RawData 是一个字节数组。你会用什么 MS SQL 数据类型来存储一个字节数组呢?二进制? - PositiveGuy
我只想读取一次,而不必将那个.p12文件存储在服务器上。我认为这就是意图。我们的领导说不要从文件中读取它,而是从数据库中读取。我会假设这意味着我应该能够将其存储在数据库中,并且永远不必再次读取该文件? - PositiveGuy
没错,一旦你读取了.p12文件,就可以将字节数组保存到数据库中。你的.p12文件是否也包含私钥?如果是这样的话,最好将其存储在证书存储区。否则,如果你只有公钥,那么将其保存到数据库中应该是可以的。 - Rohan West
似乎 RawData 不包含 FriendlyName 属性。 - Borislav Ivanov

6

使用.Export()方法,然后将其转换为Base64字符串并保存为VARCHAR(MAX)

保存方法如下:

var cert = new X509Certificate2(filename);
var stringOfCertWithPrivateKey = Convert.ToBase64String(cert.Export(X509ContentType.Pkcs12));

// Or as a regular cert, which will strip the private key out
var stringOfCertWithoutPrivateKey = Convert.ToBase64String(cert.Export(X509ContentType.Cert));

// Save either string as VARCHAR(MAX) in the DB, it's just a Base64/ASCII string now.

从数据库中取回数据后,只需执行以下操作即可进行恢复:

var certBytes = Convert.FromBase64String(stringOfCertWithPrivateKey);
var cert = new X509Certificate2(certBytes);

使用 Export() 比使用 .RawData 更好,因为您可以选择是否持久化私钥(使用 .RawData 将始终剥离它)。

您可以将结果的 Base64 字符串存储在 SQL 数据库中作为 VARCHAR(MAX) 类型,因为 Base64 字符串仅由 ASCII 字符组成(感谢这个答案)。


为什么需要使用NVARCHAR?请参见https://dev59.com/FXE95IYBdhLWcg3wPbd7 - Peter Henry
1
回答这个问题的时候,我对 SQL 的了解比今天少。我猜 NVARCHAR 的知识渗透到了这个答案中,但你是对的 @PeterHenry,它并不相关。我会将其删除。 - jezpez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接