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);
答案 0 :(得分:1)
您不能只加载字节并对其进行签名。该文件是OLE流的构建,该OLE流需要进行哈希处理,并且签名结构也可以持久保存到OLE流中。