庆军之加解密 国密

一般的国密网上都已经有很多的文章了,这里的国密算法是对的,但是,他需要 数字信封,手撸一个数字信封,算是水文吧。因为加解密有些概念我也不清楚。

代码如下:

public static byte[] Signed3(AsymmetricKeyParameter priKey, X509Certificate signCert, byte[] originData)
{
    string userId = "1234567812345678";
    byte[] byUserId = Encoding.UTF8.GetBytes(userId);

    byte[] encryptedDigest = GmUtil.SignSm3WithSm2Asn1Rs(originData, byUserId, priKey);

    var digestOid = "1.2.156.10197.1.401";
    DerObjectIdentifier data = new DerObjectIdentifier("1.2.156.10197.6.1.4.2.1");

    AlgorithmIdentifier digestAlgorithmIdentifier = new AlgorithmIdentifier(
        new DerObjectIdentifier(digestOid));
    DerSet digestAlgorithms = new DerSet(digestAlgorithmIdentifier);

    DerSequence contentInfo = new DerSequence((Asn1Encodable)data,
        originData == null ? null :
        new DerTaggedObject(0, (Asn1Encodable)new DerOctetString(originData))
        );

    DerSet certificates = certToDerSet(signCert);
    DerTaggedObject certificatesObj = new DerTaggedObject(false, 0, (Asn1Encodable)certificates);
    DerInteger DerInteger1 = new DerInteger(1);
    byte[] bsIssuer = signCert.IssuerDN.GetEncoded();
    Asn1InputStream ans = new Asn1InputStream(bsIssuer);
    Asn1Sequence issuer = (Asn1Sequence)ans.ReadObject();
    IssuerAndSerialNumber isAnds = new IssuerAndSerialNumber(X509Name.GetInstance(issuer),
        new DerInteger(signCert.SerialNumber));
DerObjectIdentifier(digestOid)));
    DerSequence signerInfo = new DerSequence((Asn1Encodable)DerInteger1,
        (Asn1Encodable)isAnds,
        (Asn1Encodable)new AlgorithmIdentifier(new DerObjectIdentifier(digestOid)),
        (Asn1Encodable)new
        AlgorithmIdentifier(new DerObjectIdentifier("1.2.156.10197.1.501")),
        (Asn1Encodable)new DerOctetString(encryptedDigest));

    DerInteger DerInteger2 = new DerInteger(1);
    DerSet signerInfoObj = new DerSet((Asn1Encodable)signerInfo);
    
    DerSequence signObj = new DerSequence((Asn1Encodable)DerInteger2,
        (Asn1Encodable)digestAlgorithms,
        (Asn1Encodable)contentInfo,
        (Asn1Encodable)certificatesObj,
        (Asn1Encodable)signerInfoObj);


    DerObjectIdentifier signedData = new DerObjectIdentifier("1.2.156.10197.6.1.4.2.2");
    DerSequence p7Sign = new DerSequence((Asn1Encodable)signedData,
        (Asn1Encodable)new DerTaggedObject(0, (Asn1Encodable)signObj));//数字信封
    byte[] signed = p7Sign.GetDerEncoded();
    return signed;
}

  

 1 public static byte[] Enveloped2(X509Certificate encCert, byte[] plainData)
 2 {
 3     string keyEncryptionAlg = "SM2";
 4     var keyEncryptionOid = Org.BouncyCastle.Asn1.GM.GMObjectIdentifiers.sm2encrypt.Id;
 5     string contentEncryptionAlg = "SM4";
 6     var contentEncryptionOid = Org.BouncyCastle.Asn1.GM.GMObjectIdentifiers.sm_scheme.Branch("104").Id;
 7 
 8     var keyData = SM4GetKey();
 9 
10     byte[] encKey = null;
11 
12     for (int i = 0; i < 10; i++)
13     {
14         try
15         {
16             encKey = Sm2Encrypt(keyData, encCert.GetPublicKey());
17             break;
18         }
19         catch (Exception e)
20         {
21             encKey = null;
22         }
23     }
24 
25     if (encKey == null)
26     {
27         throw new Exception("malformed integer");
28     }
29 
30     byte[] encData;
31     AlgorithmIdentifier contentEncryptionAlgorithm;
32 
33     if (isCbcEnc)
34     {
35         byte[] ivData = SM4GetKey();
36         encData = Sm4EncryptCBC(keyData, plainData, ivData, "SM4/CBC/PKCS7Padding");
37         contentEncryptionAlgorithm = 
38             new AlgorithmIdentifier(new DerObjectIdentifier(contentEncryptionOid), 
39             new DerOctetString(ivData));
40     }
41     else
42     {
43         encData = Sm4EncryptECB(keyData, plainData, "SM4/ECB/PKCS7Padding");
44         contentEncryptionAlgorithm = 
45             new AlgorithmIdentifier(new DerObjectIdentifier(contentEncryptionOid), null);
46     }
47 
48     byte[] issuerBytes = encCert.IssuerDN.GetEncoded();
49     Asn1InputStream asn1In = new Asn1InputStream(issuerBytes);
50     var _X509Name = X509Name.GetInstance(asn1In.ReadObject());
51 
52 
53     DerSequence recipientInfo = new DerSequence(
54         new DerInteger(0),
55         new IssuerAndSerialNumber(_X509Name, new DerInteger(encCert.SerialNumber)),
56         new AlgorithmIdentifier(new DerObjectIdentifier(keyEncryptionOid), null),
57         new DerOctetString(encKey)
58     );
59 
60     DerSet recipientInfos = new DerSet(recipientInfo);
61     DerObjectIdentifier contentType = Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.Data;
62     DerOctetString dEROctetString1 = new DerOctetString(encData);
63     DerTaggedObject encryptedContent = new DerTaggedObject(true, 0, dEROctetString1);
64 
65     DerSequence encryptedContentInfo = new DerSequence(
66         contentType,
67         contentEncryptionAlgorithm,
68         encryptedContent
69     );
70 
71     DerSequence envelopedObj = new DerSequence(
72         new DerInteger(0),
73         recipientInfos,
74         encryptedContentInfo
75     );
76 
77     DerSequence p7Env = new DerSequence(
78         envelopedData,
79         new DerTaggedObject(true, 0, envelopedObj)
80     );
81 
82     return p7Env.GetDerEncoded();
83 }
 1 public static byte[] UnEnveloped(AsymmetricKeyParameter privateKey, X509Certificate encCert, byte[] envelop)
 2 {
 3     ContentInfo content = ContentInfo.GetInstance(ToDERObject(envelop));// GetContentInfo(envelop);
 4     EnvelopedData data = EnvelopedData.GetInstance(content.Content);
 5     Asn1Set recipientInfos = data.RecipientInfos;
 6     EncryptedContentInfo encryptedContentInfo = data.EncryptedContentInfo;
 7     Asn1Sequence recipientInfo =(Asn1Sequence) recipientInfos[0];
 8     string keyEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(recipientInfo[2]).Algorithm.Id;
 9     byte[] encryptedKey = ((DerOctetString)recipientInfo[3]).GetOctets();
10 
11 
12     string contentType = encryptedContentInfo.ContentType.Id;
13     string contentEncryptionAlgorithm = encryptedContentInfo.ContentEncryptionAlgorithm.ObjectID.Id;
14     byte[] encryptedContent = encryptedContentInfo.EncryptedContent.GetOctets();
15     byte[] iv = null;
16 
17     if (encryptedContentInfo.ContentEncryptionAlgorithm.Parameters != null && !encryptedContentInfo.ContentEncryptionAlgorithm.Parameters.ToString().Equals("NULL"))
18     {
19         iv = ((DerOctetString)encryptedContentInfo.ContentEncryptionAlgorithm.Parameters).GetOctets();
20     }
21 
22     var newencryptedKey2 = decodeDerSM2Cipher(encryptedKey);
23     
24     byte[] key = Sm2Decrypt(newencryptedKey2, privateKey);
25 
26     byte[] plainData;
27     if (iv != null)
28     {
29         plainData = Sm4DecryptCBC(key, iv, encryptedContent, "SM4/CBC/PKCS7Padding");
30     }
31     else
32     {
33         plainData = Sm4DecryptECB(key, encryptedContent, "SM4/ECB/PKCS7Padding");
34     }
35 
36     return plainData;
37 }
 1 public static byte[] VerifySigned(byte[] signedData, X509Certificate signCert)
 2 {
 3 //命名空间来自CMS
 4     // 1. 解析CMS结构
 5     CmsSignedData cmsSignedData = new CmsSignedData(signedData);
 6 
 7     // 2. 获取签名数据主体
 8     SignedData signedDataStruct = SignedData.GetInstance(
 9         Asn1Object.FromByteArray(cmsSignedData.GetEncoded()));
10 
11     // 3. 检查摘要算法
12     Asn1Set digestAlgorithms = signedDataStruct.DigestAlgorithms;
13     if (digestAlgorithms.Count > 0)
14     {
15         AlgorithmIdentifier algId = AlgorithmIdentifier.GetInstance(
16             digestAlgorithms[0]);
17         CheckSignAlgOid("digestAlgorithm", algId.Algorithm.Id);
18     }
19 
20     // 4. 检查签名者数量
21     var signerInfos = cmsSignedData.GetSignerInfos().GetSigners();//.GetSigners();
22     if (signerInfos.Count != 1)
23     {
24         throw new Exception("仅支持单个签名者的PKCS#7结构");
25     }
26 
27     // 5. 获取原始数据
28     byte[] contentData = null;
29     if (cmsSignedData.SignedContent != null)
30     {
31         contentData = cmsSignedData.SignedContent.GetContent() as byte[];
32     }
33 
34     // 6. 获取签名者信息
35     SignerInformation signerInfo = null;
36     foreach (var item in signerInfos)
37     {
38         signerInfo = (SignerInformation)item;
39     }
40 
41     SignerID signerId = signerInfo.SignerID;
42 
43     // 7. 验证证书匹配
44     X509Certificate foundCert = FindCertificate(
45         cmsSignedData.GetCertificates("Collection"),
46         signerId,
47         signCert);
48 
49     // 8. 检查算法OID
50     CheckSignAlgOid("digestAlgorithm",
51         signerInfo.DigestAlgorithmID.Algorithm.Id);
52     CheckSignAlgOid("digestEncryptionAlgorithm",
53         signerInfo.EncryptionAlgorithmID.Algorithm.Id);
54 
55     // 9. 执行签名验证
56     bool isValid = signerInfo.Verify(foundCert.GetPublicKey());
57     if (!isValid)
58     {
59         Console.WriteLine("签名验证失败");
60     }
61 
62     return contentData;
63 }

 

posted @ 2025-04-07 14:44  forhells  阅读(37)  评论(0)    收藏  举报