c# - 如何使用我的私人 pfx 密钥签署 excel?
问题描述
c#如何用我的私人pfx密钥签署excel?你能大致解释一下Excel文件的哪一部分需要签名吗?
// this is our private key array read directly pfx file
byte[] pfkArray = {};
// this is our excel file
byte[] xlsArray = {};
xlsArray 的哪一部分/哪一部分需要签名?xlsArray 的所有文件或某些段/扇区?RFC?
在这里,我们可以使用一些介绍/类来签署有关 RFC 要求的文档。
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Web;
namespace Infra
{
public class SignFile
{
private const string ConstLocalRootSerial = @"1c151322b969b79047f5c5d90cb";
private const string ConstLocalSerial = @"1c041d12ac33528847ac378283";
private RSACryptoServiceProvider _key;
private readonly X509Certificate2 _publicCert;
public X509Certificate2Collection Certificates
{
get
{
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
return store.Certificates;
}
}
/// <summary>
/// Sign file/document/stream/bytes
/// </summary>
/// <param name="inputData">some data to sign -> byte[] data = new byte[1024];</param>
/// <param name="signature"></param>
/// <returns>signed data</returns>
public byte[] GetSignature(byte[] inputData)
{
//Sign the data
byte[] signature = _key.SignData(inputData, CryptoConfig.MapNameToOID("SHA256"));
return signature;
}
/// <summary>
/// Validate after sign was completed
/// </summary>
/// <param name="inputData"></param>
/// <param name="signature">signed data</param>
/// <returns>true if data was signed</returns>
public bool ValidateSignature(byte[] inputData, byte[] signature)
{
_key = (RSACryptoServiceProvider)_publicCert.PublicKey.Key;
if (!_key.VerifyData(inputData, CryptoConfig.MapNameToOID("SHA256"), signature))
throw new CryptographicException();
return true;
}
public X509Certificate2 Open()
{
var certificates = Certificates;
foreach (X509Certificate2 certificate in certificates)
{
// TODO: Just change it for BETA/FT/PROD
if (certificate.SerialNumber.ToUpper() == ConstLocalSerial.ToUpper())
{
return certificate;
}
}
throw new CryptographicException("Certificate serial number is missing from authority");
}
public SignFile()
{
_publicCert = Open();
_key = new RSACryptoServiceProvider();
_key.FromXmlString(_publicCert.PrivateKey.ToXmlString(true));
}
/// <summary>
/// Sign file with my private key
/// </summary>
/// <param name="cer">file path to cer file @"C:\mycertificate.cer"
/// string certificateFile = HttpContext.Current.Server.MapPath("~/App_Data/internal.provident.l.cer");
/// string certificateFile2 = HttpContext.Current.Request.MapPath("~/internal.provident.l.cer");
/// </param>
public SignFile(string pfx)
{
_publicCert = new X509Certificate2(pfx);
X509Certificate2 privateCert = null;
X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 cert in store.Certificates)
{
if (cert.GetCertHashString() == _publicCert.GetCertHashString())
privateCert = cert;
}
//Round-trip the key to XML and back, there might be a better way but this works
_key = new RSACryptoServiceProvider();
_key.FromXmlString(privateCert.PrivateKey.ToXmlString(true));
}
}
}
这是我不想做的
// Let me first get excel data
string excelFilePath = @"/myexcel.xls";
FileStream f = new FileStream(excelFilePath, FileMode.Open);
byte[] xlsArray = f.StreamToByteArray();
// Now we can get private key
string certFilePath = @"/certi.pfx";
FileStream f2 = new FileStream(certFilePath, FileMode.Open);
byte[] pfkArray = f.StreamToByteArray();
// Prepare for sign data
var signer = new SignFile();
// the problems here are:
// - we need to not use SHA256
// - should we need to pass entire xlsArray array???
byte[] signedData = signer.GetSignature(xlsArray);
解决方案
您不能只加载字节并对其进行签名。该文件由需要散列的 OLE 流和一个签名结构组成,该结构也被持久化到 OLE 流中......
推荐阅读
- tortoisesvn - tortoiseSVN 在哪里可以找到它的忽略列表的物理位置(win10)
- python - 如何在 Spyder 的 iPython 控制台上使用 DataLoader for PyTorch
- python - XMLParser skips attributes while parsing XML Schema file
- google-sheets - 如何像使用 Excel 公式一样将数据输入表格?
- java - 如何从 SQS 触发器调用涉及 spring cloud feign 的 lambda 函数
- android - 当我拍照时,某些 Android 设备上的应用程序崩溃
- python - 使用 datefinder 提取日期时间字符串
- python - 如何使用 pandas 跨列替换时间戳
- python - Docker - REST 不提供 python 应用程序
- c++ - 联合中的 Flatbuffers 结构不起作用(C++)