2012-03-22 68 views
12

Thông thường, người dùng sẽ có khóa riêng RSA được mã hóa PEM. Crypto ++ yêu cầu các phím này ở định dạng DER để tải. Tôi đã yêu cầu mọi người chuyển đổi thủ công tệp PEM của họ thành DER trước bằng cách sử dụng openssl như sau:Tải khóa RSA riêng được mã hóa PEM trong Crypto ++

openssl pkcs8 -in in_file.pem -out out_file.der -topk8 -nocrypt -outform der 

Điều đó làm việc tốt, nhưng một số người không hiểu cách thực hiện cũng như họ không muốn. Vì vậy, tôi muốn tự động chuyển đổi tệp PEM thành tệp DER trong chương trình.

Đơn giản như tách "----- BEGIN CERTIFICATE -----" và "----- END CERTIFICATE -----" khỏi PEM hoặc là một số chuyển đổi khác được yêu cầu như tốt? Tôi đã được thông báo rằng giữa các điểm đánh dấu đó chỉ là DER được mã hóa b64. Dưới đây là một số mã đó chứng tỏ vấn đề:

// load the private key 
CryptoPP::RSA::PrivateKey PK; 
CryptoPP::ByteQueue bytes; 

try 
{ 
    CryptoPP::FileSource File(rsa.c_str(), true, new CryptoPP::Base64Decoder()); 
    File.TransferTo(bytes); 
    bytes.MessageEnd(); 

    // This line Causes BERDecodeError when a PEM encoded file is used 
    PK.Load(bytes); 
} 

catch (CryptoPP::BERDecodeErr) 
{ 
    // Convert PEM to DER and try to load the key again 
} 

Tôi muốn tránh hệ thống các cuộc gọi đến openssl xây dựng và làm việc chuyển đổi hoàn toàn trong Crypto ++ để người dùng có thể cung cấp một trong hai định dạng và những thứ "chỉ làm việc". Cảm ơn lời khuyên nào.

+0

Bạn đang tìm kiếm bộ giải mã trong bộ nhớ hay cũng là một bộ giải mã trên đĩa? –

+0

@OrgnlDave - bất kỳ ví dụ nào sử dụng Crypto ++ đều sẽ thực hiện. – 01100110

+0

@ 01100110 - Crypto ++ hiện có hỗ trợ này dưới dạng tiện ích bổ sung. Xem [PEM Pack] (http://www.cryptopp.com/wiki/PEM_Pack) trên wiki Crypto ++. – jww

Trả lời

7

Có, đó là luồng DER được mã hóa bằng Base64. Tuy nhiên, lưu ý rằng ngoài việc xóa cả hai điểm đánh dấu BEGIN và END, trong trường hợp định dạng khóa RSA, bạn cũng cần loại bỏ bất kỳ cờ nào có thể được chèn giữa điểm đánh dấu BEGIN và dữ liệu được mã hóa. Chỉ phần còn lại mới có thể được giải mã thành công Base64. Có vẻ như bạn nạp tệp chứng chỉ đầy đủ vào bộ giải mã và cần sửa chữa.

+0

Tôi đánh giá cao câu trả lời. Tôi có thể thực hiện chuyển đổi với lệnh std :: system to openssl. Điều đó hoạt động tốt, nhưng đó là một hack. Tôi muốn thực hiện chuyển đổi từ PEM thành DER hoàn toàn bằng Crypto ++. – 01100110

+0

Chào mừng bạn đến với stackoverflow orLcount, +1 cho câu trả lời đó. –

+0

Tôi không có chuyên gia về Crypto ++, nhưng có vẻ như thư viện không hỗ trợ tải chứng chỉ được mã hóa PEM trực tiếp. Bạn cần thêm chức năng đó. Hoặc bằng cách loại bỏ các dấu đầu/cuối bằng cách sử dụng std :: string facilities trực tiếp trên biến 'rsa' của bạn, hoặc bằng cách viết' CryptoPP :: BufferedTransformation' làm cùng một công việc. – orLcount

2

Tôi biết đây là câu hỏi cũ nhưng câu hỏi khác có thể thấy điều này hữu ích. Khi bạn tách các điểm đánh dấu bạn đã để lại bằng tài liệu chính 'bên trong'. Theo số http://www.cryptopp.com/wiki/Keys_and_Formats#BER_and_DER_Encoding bạn có thể sử dụng BERDecodePrivateKey để tải ứng dụng này. Vì vậy, để tải một chìa khóa openssl rằng đã có dấu hiệu của nó tước bạn có thể làm một cái gì đó giống như

bool LoadKey(RandomNumberGenerator& rng, const std::string& file, 
    RSA::PrivateKey& key) 
{ 
    ByteQueue q; 
    FileSource KeyFile(file.c_str(), true, new Base64Decoder); 
    KeyFile.TransferTo(q); 
    key.BERDecodePrivateKey(q,false,0); // last 2 params unused 
    return key.Validate(rng, 2); 
} 
1

... Tôi muốn chuyển đổi file PEM để der tập tin tự động trong chương trình.

Vào tháng 7 năm 2014, một PEM Pack đã được cung cấp cho thư viện Crypto ++. Gói PEM là một phần thực hiện mã hóa thư cho phép bạn đọc và viết các khóa và tham số mã hóa PEM, bao gồm các khóa riêng được mã hóa. Các tệp bổ sung bao gồm hỗ trợ cho các khóa RSA, DSA, EC, ECDSA và các tham số Diffie-Hellman.

Đó là tiện ích bổ sung cho thư viện và không phải là một phần của thư viện phù hợp. Bạn tải xuống một tệp ZIP và thêm năm tệp nguồn vào thư viện. Sau đó, bạn xây dựng thư viện (Crypto ++ tự động chọn chúng). ZIP chứa năm tệp nguồn bổ sung, một kịch bản để tạo các khóa kiểm tra bằng OpenSSL, một chương trình C++ để kiểm tra đọc và viết các khóa và một kịch bản lệnh để xác minh các khóa được viết bởi Crypto ++ sử dụng OpenSSL.

Đây là cách bạn sẽ sử dụng nó:

CryptoPP::RSA::PrivateKey pk; 
CryptoPP::FileSource file("<rsa-key-file.pem>", true); 

CryptoPP::PEM_Load(file, pk); 

CryptoPP::AutoSeededRandomPool prng; 
bool = pk.Validate(prng, 3); 
if (! valid) 
    throw ... 

Nếu các phím được mã hóa, sau đó đây là cách bạn sẽ tải nó. Các PEM Pack tái thực hiện của OpenSSL của EVP_BytesToKey, vì vậy nguồn gốc chính sẽ làm việc và bạn có thể interop:

CryptoPP::RSA::PrivateKey pk; 
CryptoPP::FileSource file("<rsa-key-file.pem>", true); 

std::string pass = "<super secret password>"; 
CryptoPP::PEM_Load(file, pk, pass.data(), pass.size()); 

CryptoPP::AutoSeededRandomPool prng; 
bool = pk.Validate(prng, 3); 
if (! valid) 
    throw ... 

Ngoài ra còn có một PEM_Save, vì vậy bạn có thể viết các phím trực tiếp từ Crypto ++.Ví dụ:

// Generate it or load it from somewhere 
CryptoPP::RSA::PrivateKey pk = ...; 
CryptoPP::FileSink file("<rsa-key-file.pem>", true); 

CryptoPP::PEM_Save(file, pk); 

PEM_Save cho một chìa khóa mã hóa (hoặc phím bạn có ý định để mã hóa):

// Generate it or load it from somewhere 
CryptoPP::RSA::PrivateKey pk = ...; 
CryptoPP::FileSink file("<rsa-key-file.pem>", true); 

std::string pass = "<super secret password>"; 
CryptoPP::PEM_Save(file, pk, "AES-128-CBC", pass.data(), pass.size()); 

PEM_Load không không cần một thuật toán mã hóa bởi vì nó trong tiêu đề gói gọn. PEM_Save cần thuật toán vì không có thuật toán mặc định.

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