2014-05-24 17 views
6

tôi đang tạo ra một chìa khóa với OpenSSL, cung cấp mật khẩu từ stdin:Cách sử dụng khóa riêng RSA được mã hóa bằng PyCrypto?

openssl genpkey -algorithm RSA -out private-key.pem -outform PEM -pass stdin -des3 -pkeyopt rsa_keygen_bits:4096 

Mấu chốt sau đó trông giống như:

-----BEGIN ENCRYPTED PRIVATE KEY----- 
XXX... 
-----END ENCRYPTED PRIVATE KEY----- 

My Python mã trông giống như:

from Crypto.PublicKey import RSA 
# ... 
f = open('private-key.pem', 'r') 
r = RSA.importKey(f.read(), passphrase='some-pass') 
f.close() 

nhưng Tôi nhận được ngoại lệ:

File "/usr/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 665, in importKey 
    return self._importKeyDER(der) 
    File "/usr/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 588, in _importKeyDER 
    raise ValueError("RSA key format is not supported") 
ValueError: RSA key format is not supported 

Có gì sai?

Có thể tạo khóa RSA được mã hóa, lưu trữ nó trong một tệp và sau đó sử dụng nó với PyCrypto không? Có thể làm điều đó với OpenSSL không? Định dạng nào được hỗ trợ?

Nhập khóa công khai hoạt động tốt, tuy nhiên nó không được mã hóa.

+0

thú vị, đánh giá từ dấu vết ngăn xếp nó đang cố gắng nhập nó ở định dạng nhị phân DER, không phải trong PEM.Bạn có chắc chắn rằng bạn cung cấp tệp chính xác không? –

Trả lời

4

Giả thuyết # 1

Sau khi nhìn vào mã nguồn, tôi nghĩ rằng, tôi đã giải quyết được bí ẩn. Cách thức hoạt động của các khóa PEM được mã hóa bằng mật khẩu là PEM được giải mã thành DER và sau đó chức năng importKeyDER được gọi. Nếu mật khẩu được cung cấp không đúng, định dạng của biểu diễn DER được tạo sẽ không chính xác và bạn sẽ nhận được một ngoại lệ mà bạn đã cung cấp. Để xác nhận rằng, tôi chạy hai bài kiểm tra nhanh chóng dưới đây:

>>> from Crypto.PublicKey import RSA 
>>> f = open('<some-path>/private-key.pem','r') 
>>> r=RSA.importKey(f.read(),passphrase='foo') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 665, in importKey 
    return self._importKeyDER(der) 
    File "/usr/local/lib/python2.7/dist-packages/Crypto/PublicKey/RSA.py", line 588, in _importKeyDER 
    raise ValueError("RSA key format is not supported") 
ValueError: RSA key format is not supported 
>>> f = open('<some-path>/private-key.pem','r') 
>>> r=RSA.importKey(f.read(),passphrase='<valid-pass-phrase>') 
>>> r 
<_RSAobj @0xb7237b2c n(4096),e,d,p,q,u,private> 

Sau khi nhận được PEM từ tác giả, tôi đã nhận ra rằng giả thuyết # 1 là không hợp lệ đối với trường hợp của mình. Tôi vẫn muốn giữ nó ở đây là một trong những lý do có thể của việc nhập thất bại, vì vậy người dùng khác nhận thức được.

Giả thuyết # 2 - đây là trường hợp của tác giả.

RSA.py trông sau trong tập tin PEM để xác định loại mã hóa được áp dụng cho PEM:

Proc-Type: 4,ENCRYPTED 

Khi chìa khóa được tạo ra sử dụng "openssl genrsa ..." lệnh, chuỗi này được trình bày trong PEM trong rõ ràng, tuy nhiên khi "opensl genpkey ..." được sử dụng "Proc-Type" không có mặt.

RSA.py thậm chí không cố gắng để giải mã PEM nếu "Proc-Type" không tìm thấy:

# The encrypted PEM format 
    if lines[1].startswith(b('Proc-Type:4,ENCRYPTED')): 
    DEK = lines[2].split(b(':')) 
    .... 

Vì vậy, kết luận của tôi vào thời điểm này là chìa khóa tạo ra bởi "openssl genpkey" không được PyCrypto v 2.6.1 hỗ trợ.

Cập nhật quan trọng

Nó không làm việc trong phiên bản mới nhất 2.7a1 PyCrypto của. Bạn có thể tải về từ đây: http://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-2.7a1.tar.gz

>>> f = open('key.pem','r') 
>>> r = RSA.importKey(f.read(), passphrase='123456') 
>>> r 
<_RSAobj @0xb6f342ec n(2048),e,d,p,q,u,private> 
+0

Bạn có thể thử với phím này không? : http://pastebin.com/tcKJjdmw Mật khẩu là '123456'. Nó làm việc cho tôi với lệnh: openssl rsa -inform PEM -outform PEM -in private-key.pem -pubout, nhưng không phải với PyCrypto. – STF

+0

bạn sử dụng phiên bản openssl nào? –

+0

Đã kiểm tra RSA.py một lần nữa và thấy rằng nó tìm kiếm "Proc-Type: 4, ENCRYPTED". Nếu nó không tìm thấy nó, nó thậm chí sẽ không điều trị PEM như được mã hóa. Đây là những gì openssl của tôi tạo ra: "----- BEGIN RSA PRIVATE KEY ----- Proc-Type: 4, ENCRYPTED DEK-Info: DES-EDE3-CBC, AC78286040A62849". Có vẻ như phiên bản mới hơn của openssl sử dụng định dạng mới hơn. Hãy thử cách tạo khóa RSA cũ: "openssl genrsa -des3 -out privkey.pem 2048" –

2

Một cập nhật nhanh chóng cho những người tìm cách giải quyết vấn đề này mà không cần cài đặt một phiên bản thử nghiệm của lâu bị bỏ rơi PyCrypto.Thư viện có thể được thay thế an toàn bằng pycryptodome (https://github.com/Legrandin/pycryptodome) - nó có thể cung cấp cả thay thế drop-in cho pycrypto, và nó cũng có thể được sử dụng như một thư viện thay thế (pycryptodomex).

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