2017-06-12 60 views
0

我試圖用智能卡設備一次執行3種類型的數字簽名(SHA256),XML,PDF和文本。所有簽名都可以正常工作,但問題在於,每次簽名都需要密碼,但我只需要詢問一次。任何人都可以提出一個更好的方法來實現結果嗎?重寫X509Certificate2 PIN行爲

我想實現的,

Ask pin -> Sign XML -> Sign PDF -> Sign TEXT 

發生了什麼事是,

Ask pin -> Sign XML -> Ask pin -> Sign PDF -> Ask pin -> Sign TEXT 

然後我創建了一個共同的cmssiger對象爲PDF和文本簽名。

是現在是什麼情況發生,

Ask pin -> Sign XML -> Ask pin -> Sign PDF -> Sign TEXT 

我希望大家明白我在說什麼。

代碼爲每個簽約過程如下, XML

XAdESSignedXml signer = new XAdESSignedXml(toSign); 
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 
rsa = cert.PrivateKey as RSACryptoServiceProvider; 
signer.SigningKey = rsa; 
/*.......Elements attached......*/ 
signer.ComputeSignature(); 

PDF

private byte[] SignMsg(Byte[] msg, bool detached) 
{ 
    ContentInfo contentInfo = new ContentInfo(msg); 
    SignedCms signedCms = new SignedCms(contentInfo, detached); 
    _cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;//common cmssigner object 
    _cmsSigner.DigestAlgorithm.FriendlyName = "SHA256"; 
    signedCms.ComputeSignature(_cmsSigner, false); 
    byte[] bb = signedCms.Encode(); 
    CmsSignedData sd = new CmsSignedData(bb); 
    SignerInformationStore signers = sd.GetSignerInfos(); 
    byte[] signature = null; 
    SignerInformation signer = null; 
    foreach (SignerInformation signer_ in signers.GetSigners()) 
    { 
     signer = signer_; 
     break; 
    } 
    signature = signer.GetSignature(); 
    signer = SignerInformation.ReplaceUnsignedAttributes(signer, null); 
    IList signerInfos = new ArrayList(); 
    signerInfos.Add(signer); 
    sd = CmsSignedData.ReplaceSigners(sd, new SignerInformationStore(signerInfos)); 
    bb = sd.GetEncoded(); 
    return bb; 
} 

TEXT

public static string Sign(string msg, CmsSigner cmsSigner) //common cmssigner object 
{ 
    SHA256Managed crypt = new SHA256Managed(); 
    string hash = String.Empty; 
    byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(msg), 0, Encoding.UTF8.GetByteCount(msg)); 
    foreach (byte theByte in crypto) 
    { 
     hash += theByte.ToString("x2"); 
    } 
    ContentInfo contentInfo = new ContentInfo(Encoding.UTF8.GetBytes(hash)); 
    SignedCms cms = new SignedCms(contentInfo); 
    cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly; 
    cmsSigner.DigestAlgorithm.FriendlyName = "SHA256"; 
    cms.ComputeSignature(cmsSigner, false); 
    return Convert.ToBase64String(cms.Encode()); 
} 

提前致謝。

回答

0

引腳提示行爲是提供程序特定的實現細節。換句話說,一個加密服務提供商/密鑰存儲提供商將以一種方式行事,而另一個則會表現另一種行爲。

爲了減少引腳提示的機會,您將希望對所有操作使用一個會話,聽起來好像您正在這樣做,儘管如此回到了提供程序特定的行爲。

在RSACryptoServiceProvider的情況下,可以通過強制使用引腳提示策略的方式生成和存儲密鑰。這實際上是它暴露的唯一的引腳提示行爲,因爲這樣你堅持用這些鍵觀察到的行爲。