微信RSA加密公钥API

RSA算法使用说明(非对称加密算法,算法采用RSA/ECB/OAEPPadding模式)

1、 调用获取RSA公钥API获取RSA公钥,落地成本地文件,假设为public.pem
2、 确定public.pem文件的存放路径,同时修改代码中文件的输入路径,加载RSA公钥
3、 用标准的RSA加密库对敏感信息进行加密,选择RSA_PKCS1_OAEP_PADDING填充模式
      (eg:Java的填充方式要选 " RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING")
4、 得到进行rsa加密并转base64之后的密文
5、 将密文传给微信侧相应字段,如付款接口(enc_bank_no/enc_true_name)

接口默认输出PKCS#1格式的公钥,商户需根据自己开发的语言选择公钥格式 

RSA公钥格式PKCS#1,PKCS#8互转说明

  1. PKCS#1 转 PKCS#8:

openssl rsa -RSAPublicKey_in -in <filename> -pubout

  1. PKCS#8 转 PKCS#1:

openssl rsa -pubin -in <filename> -RSAPublicKey_out


  1. PKCS#1 格式密钥:

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEArT82k67xybiJS9AD8nNAeuDYdrtCRaxkS6cgs8L9h83eqlDTlrdw
zBVSv5V4imTq/URbXn4K0V/KJ1TwDrqOI8hamGB0fvU13WW1NcJuv41RnJVua0QA
lS3tS1JzOZpMS9BEGeFvyFF/epbi/m9+2kUWG94FccArNnBtBqqvFncXgQsm98JB
3a62NbS1ePP/hMI7Kkz+JNMyYsWkrOUFDCXAbSZkWBJekY4nGZtK1erqGRve8Jbx
TWirAm/s08rUrjOuZFA21/EI2nea3DidJMTVnXVPY2qcAjF+595shwUKyTjKB8v1
REPB3hPF1Z75O6LwuLfyPiCrCTmVoyfqjwIDAQAB
-----END RSA PUBLIC KEY-----


  1. PKCS#8 格式密钥:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArT82k67xybiJS9AD8nNA
euDYdrtCRaxkS6cgs8L9h83eqlDTlrdwzBVSv5V4imTq/URbXn4K0V/KJ1TwDrqO
I8hamGB0fvU13WW1NcJuv41RnJVua0QAlS3tS1JzOZpMS9BEGeFvyFF/epbi/m9+
lkUWG94FccArNnBtBqqvFncXgQsm98JB3a42NbS1ePP/hMI7Kkz+JNMyYsWkrOUF
DCXAbSZkWBJekY4nGZtK1erqGRve8JbxTWirAm/s08rUrjOuZFA21/EI2nea3Did
JMTVnXVPY2qcAjF+595shwUKyTjKB8v1REPB3hPF1Z75O6LwuLfyPiCrCTmVoyfq
jwIDAQAB
-----END PUBLIC KEY-----

官方文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_7&index=4

代码:

 1 public sealed class CryptoHelper
 2     {
 3         /// <summary>
 4         /// RSA密钥转Pem密钥
 5         /// </summary>
 6         /// <param name="RSAKey">RSA密钥</param>
 7         /// <param name="isPrivateKey">是否是私钥</param>
 8         /// <returns>Pem密钥</returns>
 9         public static string RSAKeyToPem(string RSAKey, bool isPrivateKey)
10         {
11             string pemKey = string.Empty;
12             var rsa = new RSACryptoServiceProvider();
13             rsa.FromXmlString(RSAKey);
14             RSAParameters rsaPara = new RSAParameters();
15             RsaKeyParameters key = null;
16             //RSA私钥
17             if (isPrivateKey)
18             {
19                 rsaPara = rsa.ExportParameters(true);
20                 key = new RsaPrivateCrtKeyParameters(
21                     new BigInteger(1, rsaPara.Modulus), new BigInteger(1, rsaPara.Exponent), new BigInteger(1, rsaPara.D),
22                     new BigInteger(1, rsaPara.P), new BigInteger(1, rsaPara.Q), new BigInteger(1, rsaPara.DP), new BigInteger(1, rsaPara.DQ),
23                     new BigInteger(1, rsaPara.InverseQ));
24             }
25             //RSA公钥
26             else
27             {
28                 rsaPara = rsa.ExportParameters(false);
29                 key = new RsaKeyParameters(false,
30                     new BigInteger(1, rsaPara.Modulus),
31                     new BigInteger(1, rsaPara.Exponent));
32             }
33             using (TextWriter sw = new StringWriter())
34             {
35                 var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
36                 pemWriter.WriteObject(key);
37                 pemWriter.Writer.Flush();
38                 pemKey = sw.ToString();
39             }
40             return pemKey;
41         }
42 
43         /// <summary>
44         /// Pem密钥转RSA密钥
45         /// </summary>
46         /// <param name="pemKey">Pem密钥</param>
47         /// <param name="isPrivateKey">是否是私钥</param>
48         /// <returns>RSA密钥</returns>
49         public static string PemToRSAKey(string pemKey, bool isPrivateKey)
50         {
51             string rsaKey = string.Empty;
52             object pemObject = null;
53             RSAParameters rsaPara = new RSAParameters();
54             using (StringReader sReader = new StringReader(pemKey))
55             {
56                 var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(sReader);
57                 pemObject = pemReader.ReadObject();
58             }
59             //RSA私钥
60             if (isPrivateKey)
61             {
62                 RsaPrivateCrtKeyParameters key = (RsaPrivateCrtKeyParameters)((AsymmetricCipherKeyPair)pemObject).Private;
63                 rsaPara = new RSAParameters
64                 {
65                     Modulus = key.Modulus.ToByteArrayUnsigned(),
66                     Exponent = key.PublicExponent.ToByteArrayUnsigned(),
67                     D = key.Exponent.ToByteArrayUnsigned(),
68                     P = key.P.ToByteArrayUnsigned(),
69                     Q = key.Q.ToByteArrayUnsigned(),
70                     DP = key.DP.ToByteArrayUnsigned(),
71                     DQ = key.DQ.ToByteArrayUnsigned(),
72                     InverseQ = key.QInv.ToByteArrayUnsigned(),
73                 };
74             }
75             //RSA公钥
76             else
77             {
78                 RsaKeyParameters key = (RsaKeyParameters)pemObject;
79                 rsaPara = new RSAParameters
80                 {
81                     Modulus = key.Modulus.ToByteArrayUnsigned(),
82                     Exponent = key.Exponent.ToByteArrayUnsigned(),
83                 };
84             }
85             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
86             rsa.ImportParameters(rsaPara);
87             using (StringWriter sw = new StringWriter())
88             {
89                 sw.Write(rsa.ToXmlString(isPrivateKey ? true : false));
90                 rsaKey = sw.ToString();
91             }
92             return rsaKey;
93         }
94 
95     }

使用示例

var pub_key = CryptoHelper.PemToRSAKey(result.pub_key, false);
var publicKey = CryptoHelper.RSAKeyToPem(pub_key, false);

加密参数算法

  1  public class Rsa
  2     {
  3         /** 默认编码字符集 */
  4         private static string DEFAULT_CHARSET = "UTF-8";
  5         /// <summary>
  6         /// RSA公钥加密
  7         /// </summary>
  8         /// <param name="content"></param>
  9         /// <param name="publicKeyPem"></param>
 10         /// <param name="charset"></param>
 11         /// <returns></returns>
 12         public static string RSAEncrypt(string content, string publicKeyPem, string charset= "UTF-8")
 13         {
 14             RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
 15             rsa.PersistKeyInCsp = false;
 16             RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsa, publicKeyPem);
 17             if (string.IsNullOrEmpty(charset))
 18             {
 19                 charset = DEFAULT_CHARSET;
 20             }
 21             byte[] data = Encoding.GetEncoding(charset).GetBytes(content);
 22             int maxBlockSize = rsa.KeySize / 8 - 11; //加密块最大长度限制
 23             if (data.Length <= maxBlockSize)
 24             {
 25                 byte[] cipherbytes = rsa.Encrypt(data, true);
 26                 return Convert.ToBase64String(cipherbytes);
 27             }
 28             MemoryStream plaiStream = new MemoryStream(data);
 29             MemoryStream crypStream = new MemoryStream();
 30             Byte[] buffer = new Byte[maxBlockSize];
 31             int blockSize = plaiStream.Read(buffer, 0, maxBlockSize);
 32             while (blockSize > 0)
 33             {
 34                 Byte[] toEncrypt = new Byte[blockSize];
 35                 Array.Copy(buffer, 0, toEncrypt, 0, blockSize);
 36                 Byte[] cryptograph = rsa.Encrypt(toEncrypt, false);
 37                 crypStream.Write(cryptograph, 0, cryptograph.Length);
 38                 blockSize = plaiStream.Read(buffer, 0, maxBlockSize);
 39             }
 40 
 41             return Convert.ToBase64String(crypStream.ToArray(), Base64FormattingOptions.None);
 42         }
 43     }
 44 /// <summary>Extension method for initializing a RSACryptoServiceProvider from PEM data string.</summary>
 45     public static class RSACryptoServiceProviderExtension
 46     {
 47         #region Methods
 48 
 49         /// <summary>Extension method which initializes an RSACryptoServiceProvider from a DER public key blob.</summary>
 50         public static void LoadPublicKeyDER(this RSACryptoServiceProvider provider, byte[] DERData)
 51         {
 52             byte[] RSAData = RSACryptoServiceProviderExtension.GetRSAFromDER(DERData);
 53             byte[] publicKeyBlob = RSACryptoServiceProviderExtension.GetPublicKeyBlobFromRSA(RSAData);
 54             provider.ImportCspBlob(publicKeyBlob);
 55         }
 56 
 57         /// <summary>Extension method which initializes an RSACryptoServiceProvider from a DER private key blob.</summary>
 58         public static void LoadPrivateKeyDER(this RSACryptoServiceProvider provider, byte[] DERData)
 59         {
 60             byte[] privateKeyBlob = RSACryptoServiceProviderExtension.GetPrivateKeyDER(DERData);
 61             provider.ImportCspBlob(privateKeyBlob);
 62         }
 63 
 64         /// <summary>Extension method which initializes an RSACryptoServiceProvider from a PEM public key string.</summary>
 65         public static void LoadPublicKeyPEM(this RSACryptoServiceProvider provider, string sPEM)
 66         {
 67             byte[] DERData = RSACryptoServiceProviderExtension.GetDERFromPEM(sPEM);
 68             RSACryptoServiceProviderExtension.LoadPublicKeyDER(provider, DERData);
 69         }
 70 
 71         /// <summary>Extension method which initializes an RSACryptoServiceProvider from a PEM private key string.</summary>
 72         public static void LoadPrivateKeyPEM(this RSACryptoServiceProvider provider, string sPEM)
 73         {
 74             byte[] DERData = RSACryptoServiceProviderExtension.GetDERFromPEM(sPEM);
 75             RSACryptoServiceProviderExtension.LoadPrivateKeyDER(provider, DERData);
 76         }
 77 
 78         /// <summary>Returns a public key blob from an RSA public key.</summary>
 79         internal static byte[] GetPublicKeyBlobFromRSA(byte[] RSAData)
 80         {
 81             byte[] data = null;
 82             UInt32 dwCertPublicKeyBlobSize = 0;
 83             if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
 84                 new IntPtr((int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
 85                 data, ref dwCertPublicKeyBlobSize))
 86             {
 87                 data = new byte[dwCertPublicKeyBlobSize];
 88                 if (!RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
 89                     new IntPtr((int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
 90                     data, ref dwCertPublicKeyBlobSize))
 91                     throw new Win32Exception(Marshal.GetLastWin32Error());
 92             }
 93             else
 94                 throw new Win32Exception(Marshal.GetLastWin32Error());
 95             return data;
 96         }
 97 
 98         /// <summary>Converts DER binary format to a CAPI CRYPT_PRIVATE_KEY_INFO structure.</summary>
 99         internal static byte[] GetPrivateKeyDER(byte[] DERData)
100         {
101             byte[] data = null;
102             UInt32 dwRSAPrivateKeyBlobSize = 0;
103             IntPtr pRSAPrivateKeyBlob = IntPtr.Zero;
104             if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.PKCS_RSA_PRIVATE_KEY),
105                 DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwRSAPrivateKeyBlobSize))
106             {
107                 data = new byte[dwRSAPrivateKeyBlobSize];
108                 if (!RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.PKCS_RSA_PRIVATE_KEY),
109                     DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwRSAPrivateKeyBlobSize))
110                     throw new Win32Exception(Marshal.GetLastWin32Error());
111             }
112             else
113                 throw new Win32Exception(Marshal.GetLastWin32Error());
114             return data;
115         }
116 
117         /// <summary>Converts DER binary format to a CAPI CERT_PUBLIC_KEY_INFO structure containing an RSA key.</summary>
118         internal static byte[] GetRSAFromDER(byte[] DERData)
119         {
120             byte[] data = null;
121             byte[] publicKey = null;
122             CERT_PUBLIC_KEY_INFO info;
123             UInt32 dwCertPublicKeyInfoSize = 0;
124             IntPtr pCertPublicKeyInfo = IntPtr.Zero;
125             if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO),
126                 DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize))
127             {
128                 data = new byte[dwCertPublicKeyInfoSize];
129                 if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO),
130                     DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize))
131                 {
132                     GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
133                     try
134                     {
135                         info = (CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(CERT_PUBLIC_KEY_INFO));
136                         publicKey = new byte[info.PublicKey.cbData];
137                         Marshal.Copy(info.PublicKey.pbData, publicKey, 0, publicKey.Length);
138                     }
139                     finally
140                     {
141                         handle.Free();
142                     }
143                 }
144                 else
145                     throw new Win32Exception(Marshal.GetLastWin32Error());
146             }
147             else
148                 throw new Win32Exception(Marshal.GetLastWin32Error());
149             return publicKey;
150         }
151 
152         /// <summary>Extracts the binary data from a PEM file.</summary>
153         internal static byte[] GetDERFromPEM(string sPEM)
154         {
155             UInt32 dwSkip, dwFlags;
156             UInt32 dwBinarySize = 0;
157 
158             if (!RSACryptoServiceProviderExtension.CryptStringToBinary(sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, null, ref dwBinarySize, out dwSkip, out dwFlags))
159                 throw new Win32Exception(Marshal.GetLastWin32Error());
160 
161             byte[] decodedData = new byte[dwBinarySize];
162             if (!RSACryptoServiceProviderExtension.CryptStringToBinary(sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, decodedData, ref dwBinarySize, out dwSkip, out dwFlags))
163                 throw new Win32Exception(Marshal.GetLastWin32Error());
164             return decodedData;
165         }
166 
167         #endregion Methods
168 
169         #region P/Invoke Constants
170 
171         /// <summary>Enumeration derived from Crypto API.</summary>
172         internal enum CRYPT_ACQUIRE_CONTEXT_FLAGS : uint
173         {
174             CRYPT_NEWKEYSET = 0x8,
175             CRYPT_DELETEKEYSET = 0x10,
176             CRYPT_MACHINE_KEYSET = 0x20,
177             CRYPT_SILENT = 0x40,
178             CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x80,
179             CRYPT_VERIFYCONTEXT = 0xF0000000
180         }
181 
182         /// <summary>Enumeration derived from Crypto API.</summary>
183         internal enum CRYPT_PROVIDER_TYPE : uint
184         {
185             PROV_RSA_FULL = 1
186         }
187 
188         /// <summary>Enumeration derived from Crypto API.</summary>
189         internal enum CRYPT_DECODE_FLAGS : uint
190         {
191             NONE = 0,
192             CRYPT_DECODE_ALLOC_FLAG = 0x8000
193         }
194 
195         /// <summary>Enumeration derived from Crypto API.</summary>
196         internal enum CRYPT_ENCODING_FLAGS : uint
197         {
198             PKCS_7_ASN_ENCODING = 0x00010000,
199             X509_ASN_ENCODING = 0x00000001,
200         }
201 
202         /// <summary>Enumeration derived from Crypto API.</summary>
203         internal enum CRYPT_OUTPUT_TYPES : int
204         {
205             X509_PUBLIC_KEY_INFO = 8,
206             RSA_CSP_PUBLICKEYBLOB = 19,
207             PKCS_RSA_PRIVATE_KEY = 43,
208             PKCS_PRIVATE_KEY_INFO = 44
209         }
210 
211         /// <summary>Enumeration derived from Crypto API.</summary>
212         internal enum CRYPT_STRING_FLAGS : uint
213         {
214             CRYPT_STRING_BASE64HEADER = 0,
215             CRYPT_STRING_BASE64 = 1,
216             CRYPT_STRING_BINARY = 2,
217             CRYPT_STRING_BASE64REQUESTHEADER = 3,
218             CRYPT_STRING_HEX = 4,
219             CRYPT_STRING_HEXASCII = 5,
220             CRYPT_STRING_BASE64_ANY = 6,
221             CRYPT_STRING_ANY = 7,
222             CRYPT_STRING_HEX_ANY = 8,
223             CRYPT_STRING_BASE64X509CRLHEADER = 9,
224             CRYPT_STRING_HEXADDR = 10,
225             CRYPT_STRING_HEXASCIIADDR = 11,
226             CRYPT_STRING_HEXRAW = 12,
227             CRYPT_STRING_NOCRLF = 0x40000000,
228             CRYPT_STRING_NOCR = 0x80000000
229         }
230 
231         #endregion P/Invoke Constants
232 
233         #region P/Invoke Structures
234 
235         /// <summary>Structure from Crypto API.</summary>
236         [StructLayout(LayoutKind.Sequential)]
237         internal struct CRYPT_OBJID_BLOB
238         {
239             internal UInt32 cbData;
240             internal IntPtr pbData;
241         }
242 
243         /// <summary>Structure from Crypto API.</summary>
244         [StructLayout(LayoutKind.Sequential)]
245         internal struct CRYPT_ALGORITHM_IDENTIFIER
246         {
247             internal IntPtr pszObjId;
248             internal CRYPT_OBJID_BLOB Parameters;
249         }
250 
251         /// <summary>Structure from Crypto API.</summary>
252         [StructLayout(LayoutKind.Sequential)]
253         struct CRYPT_BIT_BLOB
254         {
255             internal UInt32 cbData;
256             internal IntPtr pbData;
257             internal UInt32 cUnusedBits;
258         }
259 
260         /// <summary>Structure from Crypto API.</summary>
261         [StructLayout(LayoutKind.Sequential)]
262         struct CERT_PUBLIC_KEY_INFO
263         {
264             internal CRYPT_ALGORITHM_IDENTIFIER Algorithm;
265             internal CRYPT_BIT_BLOB PublicKey;
266         }
267 
268         #endregion P/Invoke Structures
269 
270         #region P/Invoke Functions
271 
272         /// <summary>Function for Crypto API.</summary>
273         [DllImport("advapi32.dll", SetLastError = true)]
274         [return: MarshalAs(UnmanagedType.Bool)]
275         internal static extern bool CryptDestroyKey(IntPtr hKey);
276 
277         /// <summary>Function for Crypto API.</summary>
278         [DllImport("advapi32.dll", SetLastError = true)]
279         [return: MarshalAs(UnmanagedType.Bool)]
280         internal static extern bool CryptImportKey(IntPtr hProv, byte[] pbKeyData, UInt32 dwDataLen, IntPtr hPubKey, UInt32 dwFlags, ref IntPtr hKey);
281 
282         /// <summary>Function for Crypto API.</summary>
283         [DllImport("advapi32.dll", SetLastError = true)]
284         [return: MarshalAs(UnmanagedType.Bool)]
285         internal static extern bool CryptReleaseContext(IntPtr hProv, Int32 dwFlags);
286 
287         /// <summary>Function for Crypto API.</summary>
288         [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
289         [return: MarshalAs(UnmanagedType.Bool)]
290         internal static extern bool CryptAcquireContext(ref IntPtr hProv, string pszContainer, string pszProvider, CRYPT_PROVIDER_TYPE dwProvType, CRYPT_ACQUIRE_CONTEXT_FLAGS dwFlags);
291 
292         /// <summary>Function from Crypto API.</summary>
293         [DllImport("crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)]
294         [return: MarshalAs(UnmanagedType.Bool)]
295         internal static extern bool CryptStringToBinary(string sPEM, UInt32 sPEMLength, CRYPT_STRING_FLAGS dwFlags, [Out] byte[] pbBinary, ref UInt32 pcbBinary, out UInt32 pdwSkip, out UInt32 pdwFlags);
296 
297         /// <summary>Function from Crypto API.</summary>
298         [DllImport("crypt32.dll", SetLastError = true)]
299         [return: MarshalAs(UnmanagedType.Bool)]
300         internal static extern bool CryptDecodeObjectEx(CRYPT_ENCODING_FLAGS dwCertEncodingType, IntPtr lpszStructType, byte[] pbEncoded, UInt32 cbEncoded, CRYPT_DECODE_FLAGS dwFlags, IntPtr pDecodePara, ref byte[] pvStructInfo, ref UInt32 pcbStructInfo);
301 
302         /// <summary>Function from Crypto API.</summary>
303         [DllImport("crypt32.dll", SetLastError = true)]
304         [return: MarshalAs(UnmanagedType.Bool)]
305         internal static extern bool CryptDecodeObject(CRYPT_ENCODING_FLAGS dwCertEncodingType, IntPtr lpszStructType, byte[] pbEncoded, UInt32 cbEncoded, CRYPT_DECODE_FLAGS flags, [In, Out] byte[] pvStructInfo, ref UInt32 cbStructInfo);
306 
307         #endregion P/Invoke Functions
308     }

 需要引用BouncyCastle.Crypto.dll

原文地址:https://www.cnblogs.com/liuchangxu/p/13398644.html