2010-01-11 35 views
7

đây có lẽ là câu hỏi n00b, nhưng tôi không thực sự có bất kỳ kinh nghiệm nào trong lĩnh vực này.Làm cách nào để tạo tệp PKCS12 .p12 trong C#?

Tôi cần tạo gói p12 chứa chứng chỉ X509 và khóa cá nhân. Tôi hiện có hai đối tượng, X509Certificate2 và đối tượng RSAParameters chứa thông tin quan trọng. Làm cách nào để kết hợp chúng thành tệp p12?

Tôi không thể tìm thấy bất kỳ thông tin nào về việc này.

Tôi cũng có một đối tượng RSACryptoServiceProvider có các tham số từ các RSAParameters được nhập vào nó nếu nó giúp.

Một số nền bổ sung. Tôi nhận được chứng chỉ của mình từ Cơ quan đăng ký VeriSign mà chúng tôi đã cài đặt tại đây. Việc này được thực hiện bằng cách tạo yêu cầu chứng chỉ PCKS # 10. Tôi tạo đối tượng chứng chỉ của mình bằng cách đọc trong một mảng byte dữ liệu mà RA đưa vào cơ sở dữ liệu.

RsaPrivateCrtKeyParameters KeyParams = (RsaPrivateCrtKeyParameters)this.KeyPair.Private; 
RSAParameters rsaParameters = new RSAParameters(); 

rsaParameters.Modulus = KeyParams.Modulus.ToByteArrayUnsigned(); 
rsaParameters.P = KeyParams.P.ToByteArrayUnsigned(); 
rsaParameters.Q = KeyParams.Q.ToByteArrayUnsigned(); 
rsaParameters.DP = KeyParams.DP.ToByteArrayUnsigned(); 
rsaParameters.DQ = KeyParams.DQ.ToByteArrayUnsigned(); 
rsaParameters.InverseQ = KeyParams.QInv.ToByteArrayUnsigned(); 
rsaParameters.D = KeyParams.Exponent.ToByteArrayUnsigned(); 
rsaParameters.Exponent = KeyParams.PublicExponent.ToByteArrayUnsigned(); 

RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(); 
rsaKey.ImportParameters(rsaParameters); 

this.Certificate.PrivateKey = rsaKey; 

byte[] p12 = this.Certificate.Export(X509ContentType.Pkcs12, "password"); 

File.WriteAllBytes(fileName, p12); 

hệ PKCS10 (sử dụng thư viện BouncyCastle)

509Name name = new X509Name(String.Concat(SubjectCommonName, "=", firstName, " ", lastName)); 
RsaKeyPairGenerator rkpg = new RsaKeyPairGenerator(); 
rkpg.Init(new KeyGenerationParameters(new SecureRandom(), 1024)); 
this.KeyPair = rkpg.GenerateKeyPair(); 

// PKCS #10 Certificate Signing Request 
Pkcs10CertificationRequest csr = new Pkcs10CertificationRequest("SHA1WITHRSA", name, this.KeyPair.Public, null, this.KeyPair.Private); 
byte[] request = Base64.Encode(csr.GetEncoded()); 
ASCIIEncoding encoder = new ASCIIEncoding(); 
return encoder.GetString(request); 

Yêu cầu cert (trừ các tiêu đề http bưu điện). tham số public_key là mã hóa base64, CSR được định dạng pkcs10. (Tôi đã đặt các ngắt dòng sau mỗi tham số chỉ vì vậy nó dễ dàng hơn để đọc ở đây, họ không có trong bài http thực tế)

operation=AutoAuthOSUserSubmit& 
form_file=..%2ffdf%2fclient%2fuserEnrollMS.fdf& 
authenticate=NO& 
public_key_format=pkcs10& 
country=NZ& 
mail_firstName=Daniel& 
mail_lastName=Mapletoft& 
[email protected]& 
challenge=1234& 
public_key=MIIBTzCBuwIBADAUMRIwEAYDVQQDDAlTaW1vbiBEb2UwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANZD8M7gjUq1vBWq4w25x3SNhet4T+uCV3ebnAB5ws9f2YQevd9QeSfoPWw/pyJ/mJRDZDLjYzG63VQUzrXyBx3PZhmWqWaDECAYSssOYTfTMWPns0sRsyg1f35f4mh0ZXieiPYdv8r9CVjG9woa15LA1cYI0b93alM/z+OoMLxNAgMBAAEwCwYJKoZIhvcNAQEFA4GBAIB9buu5sycjdAgyV+UMAlzYKlENrQmI2/36ZZ4q3sx5bIyLm9tOEexbNzkk86kcGQhL2w/0oA5UpUCUU4IIf9u+lhpMoUlbHKH4tosswMwVEiFpfIWrL4M9X7+TW4Lj1aGf2T+xgKhWeo+cBSGexxvHo27OaH9d1NVDozEJ6c7i 

Đây là sản phẩm từ Certificate.GetRawCertDataString()

3082036F30820257A003020102021034914BB0AF5A48704B56C89DE8B1BBFD300D06092A864886F70D0101050500304D310B3009060355040613024E5A31283026060355040A131F4669727374204D6F727467616765205365727669636573204C696D69746564311430120603550403130B464D5320526F6F74204341301E170D3130303132313030303030305A170D3131303132313233353935395A305B31243022060355040A141B4669727374204D6F727467616765205365727669636573204C7464311F301D060355040B1416466F72205465737420507572706F736573204F6E6C79311230100603550403140953696D6F6E20446F6530819F300D06092A864886F70D010101050003818D0030818902818100D643F0CEE08D4AB5BC15AAE30DB9C7748D85EB784FEB8257779B9C0079C2CF5FD9841EBDDF507927E83D6C3FA7227F9894436432E36331BADD5414CEB5F2071DCF661996A966831020184ACB0E6137D33163E7B34B11B328357F7E5FE2687465789E88F61DBFCAFD0958C6F70A1AD792C0D5C608D1BF776A533FCFE3A830BC4D0203010001A381C03081BD30090603551D1304023000300E0603551D0F0101FF0404030205A030600603551D1F0101FF045630543052A050A04E864C687474703A2F2F6F6E7369746563726C2E766572697369676E2E636F6D2F46697273744D6F72746761676553657276696365734C746450726F70656C6C632F4C617465737443524C2E63726C301F0603551D230418301680148B2A2C583903B2619F16E73D3DF1704DB1F3D4E2301D0603551D0E0416041411A6D5EBC14D7C226502EC340F70237D23431D0B300D06092A864886F70D010105050003820101008EFD93EF777F2D196FC8633C5A8347CA886320E59AF8AF8D3AA901AEF0ADF75EDD2D3C4495CF70F1E4516AA224F3731B6EE66DCB332FD88C03255DA9D12202DD3DF619EE55443F53773FD03C808B5B66AEEB39A3E20B866DC22D92010785A2729C269E35ED6B2036014628850B8E8A40A501F3C7EECA49A4B7E957B496ECD8A27702D7230C40580F94C69E83A0AEFD9347625B529E3ACDD2A5FEB7B946BEE9BE9DA9AA52E14AEC790C66E8A670AA1D53518DEFB66FE6BC33A57BB6A59C75C6DFADE5E961A9A03C3FFDC559FC9ADD565D345975B99BEF5F973D331E60A3FEFEF713C6C630D80222AD9541BC12F1E92379EF5CBECE81CA5E327FD32FDC28AB52D7 

đây là nội dung của mảng từ byte [] array1 = certKey.ExportCspBlob (false);

6,2,0,0,0,164,0,0,82,83,65,49,0,4,0,0,1,0,1,0,77,188,48,168,227,207,63,83,106,119,191,209,8,198,213,192,146,215,26,10,247,198,88,9,253,202,191,29,246,136,158,120,101,116,104,226,95,126,127,53,40,179,17,75,179,231,99,49,211,55,97,14,203,74,24,32,16,131,102,169,150,25,102,207,29,7,242,181,206,20,84,221,186,49,99,227,50,100,67,148,152,127,34,167,63,108,61,232,39,121,80,223,189,30,132,217,95,207,194,121,0,156,155,119,87,130,235,79,120,235,133,141,116,199,185,13,227,170,21,188,181,74,141,224,206,240,67,214 

đây là nội dung của mảng từ byte [] array2 = rsaKey.ExportCspBlob (false);

6,2,0,0,0,164,0,0,82,83,65,49,0,4,0,0,1,0,1,0,77,188,48,168,227,207,63,83,106,119,191,209,8,198,213,192,146,215,26,10,247,198,88,9,253,202,191,29,246,136,158,120,101,116,104,226,95,126,127,53,40,179,17,75,179,231,99,49,211,55,97,14,203,74,24,32,16,131,102,169,150,25,102,207,29,7,242,181,206,20,84,221,186,49,99,227,50,100,67,148,152,127,34,167,63,108,61,232,39,121,80,223,189,30,132,217,95,207,194,121,0,156,155,119,87,130,235,79,120,235,133,141,116,199,185,13,227,170,21,188,181,74,141,224,206,240,67,214 
+0

Chào mừng bạn đến với SO Family DangerMice! Mẹo nhỏ mặc dù: bạn có thể chỉnh sửa câu trả lời của mình bằng cách nhấp vào liên kết "chỉnh sửa" màu xám nhỏ bên dưới câu hỏi của bạn. – RCIX

+0

Cảm ơn RCIX, đã hoàn thành :) – DangerMice

Trả lời

5

Hãy thử điều này:

RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(); 
rsaKey.ImportParameters(rsaParameters); 

X509Certificate2 cert = ... 

cert.PrivateKey = rsaKey; 

cert.Export(X509ContentType.Pkcs12, "password"); 

Vì bạn vẫn nhận được không phù hợp, nhưng không thể tìm thấy bất kỳ sự khác biệt giữa các phím, hãy thử để chèn kiểm tra này (nó sẽ tái tạo những gì khuôn khổ NET thực hiện trong nội bộ):

RSACryptoServiceProvider certKey = (RSACryptoServiceProvider) cert.PublicKey.Key; 
byte[] array1 = certKey.ExportCspBlob(false); 
byte[] array2 = rsaKey.ExportCspBlob(false); 
if(array1.Length!=array2.Length) 
    throw new Exception("key mismatch"); 
for (int i = 8; i < array1.Length; i++){ // skip blobheader 
    if (array1[i] != array2[i]){ 
    throw new Exception("key mismatch"); 
    } 
} 

Có vẻ như đã xảy ra sự cố với khóa của bạn. Bạn có thể tạo ra một khóa RSA mới giữa việc phát hành yêu cầu chứng chỉ và nhận chứng chỉ không?

Đây là một bãi chứa của chứng chỉ theo yêu cầu của bạn:

0 30 342: SEQUENCE { 
    4 30 194: SEQUENCE { 
    7 02 1:  INTEGER 0 
    10 30 27:  SEQUENCE { 
    12 31 25:  SET { 
    14 30 23:   SEQUENCE { 
    16 06 3:   OBJECT IDENTIFIER commonName (2 5 4 3) 
    21 0C 16:   UTF8String 'Daniel Mapletoft' 
      :   } 
      :   } 
      :  } 
    39 30 159:  SEQUENCE { 
    42 30 13:  SEQUENCE { 
    44 06 9:   OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1) 
    55 05 0:   NULL 
      :   } 
    57 03 141:  BIT STRING 0 unused bits, encapsulates { 
    61 30 137:   SEQUENCE { 
    64 02 129:    INTEGER 
      :    00 95 83 2A AB 16 9D 7F 16 87 40 A4 09 74 5F 9D 
      :    81 04 B0 41 C1 75 9C C9 CD D0 52 EF 61 09 EF F5 
      :    9B 40 1D D4 79 E0 4B 17 6C 1E 62 73 38 D8 69 92 
      :    31 C4 E0 84 07 4B 2E FD 53 6D 24 95 59 12 43 8E 
      :    82 35 1D 62 79 89 C2 88 38 57 3D 1F 15 8D B9 CC 
      :    FA F4 41 23 BA FD ED 51 69 F7 7A E7 03 72 A2 DA 
      :    A9 08 65 17 DA 90 E3 7B C4 2C 85 6A 3F AF 83 AC 
      :    E5 00 37 7A 98 14 03 EE 68 37 CB E7 0A 1A 49 5F 
      :      [ Another 1 bytes skipped ] 
196 02 3:    INTEGER 65537 
      :    } 
      :   } 
      :  } 
      :  } 
201 30 11: SEQUENCE { 
203 06 9:  OBJECT IDENTIFIER 
      :  sha1withRSAEncryption (1 2 840 113549 1 1 5) 
      :  } 
214 03 129: BIT STRING 0 unused bits 
      :  70 D5 29 EB F3 2A 34 13 3F E6 DE 78 35 FB 79 BD 
      :  6D ED 8E 89 D9 B0 8F C1 7C 7D 42 37 B8 3E 5B 00 
      :  C2 26 A4 E5 77 26 01 86 63 E1 BB 4D 9C CE 7A 10 
      :  FF 8E BF 77 1B 0E F9 EE 38 1F 1F A1 04 24 D7 6A 
      :  B6 28 3A 88 F5 54 D0 88 46 92 6E 5D 7E 7C CE 87 
      :  99 F9 DC 85 99 33 8C 9D BD 73 E2 23 8A 9A 97 B0 
      :  3A 9B 36 51 58 FD B7 0F 60 3D FB 5F 4F 06 A0 CE 
      :  30 7F 56 B6 53 5E FE 64 7D 8A 30 92 FB BA A4 C6 
      : } 

và đây là một bãi chứa của chứng chỉ của bạn:

0 30 886: SEQUENCE { 
    4 30 606: SEQUENCE { 
    8 A0 3:  [0] { 
    10 02 1:  INTEGER 2 
      :  } 
    13 02 16:  INTEGER 
      :  6E F0 A9 78 7D 3C D4 05 4E 90 13 DC 9D 34 77 2C 
    31 30 13:  SEQUENCE { 
    33 06 9:  OBJECT IDENTIFIER 
      :   sha1withRSAEncryption (1 2 840 113549 1 1 5) 
    44 05 0:  NULL 
      :  } 
    46 30 77:  SEQUENCE { 
    48 31 11:  SET { 
    50 30 9:   SEQUENCE { 
    52 06 3:   OBJECT IDENTIFIER countryName (2 5 4 6) 
    57 13 2:   PrintableString 'NZ' 
      :   } 
      :   } 
    61 31 40:  SET { 
    63 30 38:   SEQUENCE { 
    65 06 3:   OBJECT IDENTIFIER organizationName (2 5 4 10) 
    70 13 31:   PrintableString 'First Mortgage Services Limited' 
      :   } 
      :   } 
103 31 20:  SET { 
105 30 18:   SEQUENCE { 
107 06 3:   OBJECT IDENTIFIER commonName (2 5 4 3) 
112 13 11:   PrintableString 'FMS Root CA' 
      :   } 
      :   } 
      :  } 
125 30 30:  SEQUENCE { 
127 17 13:  UTCTime '091222000000Z' 
142 17 13:  UTCTime '101222235959Z' 
      :  } 
157 30 98:  SEQUENCE { 
159 31 36:  SET { 
161 30 34:   SEQUENCE { 
163 06 3:   OBJECT IDENTIFIER organizationName (2 5 4 10) 
168 14 27:   TeletexString 'First Mortgage Services Ltd' 
      :   } 
      :   } 
197 31 31:  SET { 
199 30 29:   SEQUENCE { 
201 06 3:   OBJECT IDENTIFIER organizationalUnitName (2 5 4 11) 
206 14 22:   TeletexString 'For Test Purposes Only' 
      :   } 
      :   } 
230 31 25:  SET { 
232 30 23:   SEQUENCE { 
234 06 3:   OBJECT IDENTIFIER commonName (2 5 4 3) 
239 14 16:   TeletexString 'Daniel Mapletoft' 
      :   } 
      :   } 
      :  } 
257 30 159:  SEQUENCE { 
260 30 13:  SEQUENCE { 
262 06 9:   OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1) 
273 05 0:   NULL 
      :   } 
275 03 141:  BIT STRING 0 unused bits, encapsulates { 
279 30 137:   SEQUENCE { 
282 02 129:    INTEGER 
      :    00 CD 08 AE 3E E3 5A E4 5E 50 28 29 5E 65 05 DA 
      :    1A E1 9C 50 44 4A F0 06 AA 75 1A 8F F0 75 4C AA 
      :    47 4B D5 8F 04 B5 CE 98 C5 0D 99 54 36 E9 EF 2E 
      :    7D CD DF FA 46 B2 7D 76 E5 74 19 AD 3E F0 52 52 
      :    C7 F8 86 E6 78 32 90 EB 2F 12 3F 7A 31 4B 15 E9 
      :    2A 9D 75 91 EA 31 9F 4E 98 A6 06 81 DD 98 1B 1A 
      :    DB FE 1F 2E BD 2E 32 60 5A 54 7C 0E 48 6A AB 6C 
      :    C6 F6 E2 F2 FD 4A BE 5A BD E0 DF 0C 21 B6 4C 9E 
      :      [ Another 1 bytes skipped ] 
414 02 3:    INTEGER 65537 
      :    } 
      :   } 
      :  } 
419 A3 192:  [3] { 
422 30 189:  SEQUENCE { 
425 30 9:   SEQUENCE { 
427 06 3:   OBJECT IDENTIFIER basicConstraints (2 5 29 19) 
432 04 2:   OCTET STRING, encapsulates { 
434 30 0:    SEQUENCE {} 
      :    } 
      :   } 
436 30 14:   SEQUENCE { 
438 06 3:   OBJECT IDENTIFIER keyUsage (2 5 29 15) 
443 01 1:   BOOLEAN TRUE 
446 04 4:   OCTET STRING, encapsulates { 
448 03 2:    BIT STRING 5 unused bits 
      :     '101'B 
      :    } 
      :   } 
452 30 96:   SEQUENCE { 
454 06 3:   OBJECT IDENTIFIER cRLDistributionPoints (2 5 29 31) 
459 01 1:   BOOLEAN TRUE 
462 04 86:   OCTET STRING, encapsulates { 
464 30 84:    SEQUENCE { 
466 30 82:     SEQUENCE { 
468 A0 80:     [0] { 
470 A0 78:      [0] { 
472 86 76:      [6] 
      :     'http://onsitecrl.verisign.com/FirstMortgageServi' 
      :     'cesLtdPropellc/LatestCRL.crl' 
      :      } 
      :      } 
      :     } 
      :     } 
      :    } 
      :   } 
550 30 31:   SEQUENCE { 
552 06 3:   OBJECT IDENTIFIER authorityKeyIdentifier (2 5 29 35) 
557 04 24:   OCTET STRING, encapsulates { 
559 30 22:    SEQUENCE { 
561 80 20:     [0] 
      :     8B 2A 2C 58 39 03 B2 61 9F 16 E7 3D 3D F1 70 4D 
      :     B1 F3 D4 E2 
      :     } 
      :    } 
      :   } 
583 30 29:   SEQUENCE { 
585 06 3:   OBJECT IDENTIFIER subjectKeyIdentifier (2 5 29 14) 
590 04 22:   OCTET STRING, encapsulates { 
592 04 20:    OCTET STRING 
      :     3E 91 DB A0 9C B4 A1 CB 68 CC 70 D0 0A 29 D6 BF 
      :     4E 68 10 AB 
      :    } 
      :   } 
      :   } 
      :  } 
      :  } 
614 30 13: SEQUENCE { 
616 06 9:  OBJECT IDENTIFIER 
      :  sha1withRSAEncryption (1 2 840 113549 1 1 5) 
627 05 0:  NULL 
      :  } 
629 03 257: BIT STRING 0 unused bits 
      :  3E C3 A3 F3 5F 3E 29 37 4D 33 E3 F5 F2 89 42 78 
      :  AC CD 59 14 E9 CC FF 20 8F 98 34 7B F0 F4 D2 96 
      :  EC 58 53 61 E4 3E D0 02 CF FF 30 C8 77 D0 6F 94 
      :  37 72 3C B7 90 6E 38 10 59 8C F8 06 B0 61 55 65 
      :  58 96 30 7B 9A 58 FF DB 15 7C FA F9 1F 64 5E DC 
      :  E8 63 EE EE 90 B1 18 3C 6A 11 62 73 91 CF DE DB 
      :  34 F5 67 4F C9 89 77 5C 36 71 FC 11 27 07 C5 76 
      :  BB 79 B8 8E 19 E8 E2 5B D7 A5 23 BA D8 19 7C 74 
      :    [ Another 128 bytes skipped ] 
      : } 

các số nguyên bắt đầu bằng "00 95 83 2A" trong yêu cầu và với "00 CD 08 AE" trong chứng chỉ là các mô-đun RSA của khóa công khai.

Giá trị trong đầu ra từ ExportCspBlob được đảo ngược, vì Microsoft sử dụng định dạng nhỏ, nhưng nếu bạn bắt đầu từ cuối certKey.ExportCspBlob(false), bạn sẽ nhận ra: 205 = 0xCD, 8 = 0x08, 174 = 0xAE. Mặt khác, rsaKey.ExportCspBlob(false) chứa 166 = 0xA6, 154 = 0x9A, 180 = 0xB4, đây là một mô đun RSA khác.

Bạn có chắc chắn rằng tất cả các giá trị đã bán của bạn là từ cùng một quy trình cấp chứng chỉ?

+0

có khác gì so với thực hiện Certificate.Export (X509ContentType.Pkcs12, mật khẩu) không? Ví dụ tôi đã xem xét cho điều này không cho thấy làm thế nào để bao gồm các khóa riêng. Lưu ý chứng chỉ của tôi.HasPrivateKey là Null. – DangerMice

+0

Tôi đang cố gắng sử dụng phương pháp bạn đã có trước đây trong câu trả lời này (PFXExportCertStoreEx) bằng cách sử dụng lớp tôi tìm thấy ở đây http://blogs.msdn.com/dcook/attachment/9143036.ashx Tuy nhiên, việc này giảm chứng chỉ thân thiện tên và tên thay thế chủ đề mà tôi đã thêm vào các phạm vi cert. Có ai có thể hướng dẫn tôi cách thay đổi lớp học trên để bao gồm những điều này không? Tôi không biết đủ C++ để có thể dịch thành C# http://msdn.microsoft.com/en-us/library/aa376039 (VS.85).aspx Cảm ơn – DangerMice

+0

Xin chào Rasmus, vâng tôi đã thử phương thức cert.Export đầu tiên, như bạn mô tả ở trên, tuy nhiên trên cert.PrivateKey = rsaKey Tôi nhận được lỗi "Khóa công khai của chứng chỉ không khớp với giá trị được chỉ định." Xem mã tôi đã thêm vào câu hỏi. Đối tượng RsaPrivateCrtKeyParameters đến từ thư viện BouncyCastle mà tôi đã sử dụng để tạo các khóa của mình và đưa chúng vào yêu cầu chứng chỉ của mình. – DangerMice

Các vấn đề liên quan