2012-06-10 48 views
7

Tôi chỉ có một số kiến ​​thức lý thuyết rất thô sơ về RSA.trao đổi khóa công khai/riêng tư trong mã hóa/giải mã OCSEP PKCS # 1

Trong khi đọc các nguồn khác nhau về cách sử dụng nó trong thực tế, có vẻ như PKCS # 1 OAEP sẽ là một điều tốt.

Để thực hiện thử nghiệm, tôi sử dụng Python với PyCrypto. Ví dụ. this là một ví dụ sử dụng PKCS # 1 OAEP.

Mã hóa bằng khóa công khai và sau đó giải mã bằng khóa riêng hoạt động tốt. Ví dụ. công chúng có thể gửi một số dữ liệu cho người X bằng khóa riêng.

Từ hiểu biết cơ bản về cách thức hoạt động của RSA, tôi nghĩ rằng tôi có thể trao đổi khóa công khai/riêng tư, nghĩa là tôi có thể sử dụng khóa công khai để mã hóa và khóa riêng để giải mã. Ví dụ. người X có thể mã hóa một số dữ liệu bằng khóa riêng của nó và công chúng có thể giải mã nó bằng cách sử dụng khóa công khai. Nếu giải mã hoạt động tốt, điều này cung cấp một số loại bằng chứng cho thấy dữ liệu đến từ người X.

PyCrypto than phiền khi tôi cố gắng giải mã bằng khóa công khai.

Từ đọc mã nguồn PyCrypto, trong _RSAKey._decrypt function (here), có vẻ như đối tượng chính bản thân biết nếu nó là chìa khóa tư nhân hoặc công cộng và khác nhau giữa chúng (trước sự ngạc nhiên của tôi, một lần nữa dựa trên của tôi rất cơ bản RSA sự hiểu biết).

Từ đó, có vẻ như tôi có thể hack chức năng giải mã để nó sử dụng khóa công khai. Hoặc hơi khác: tôi chỉ có thể trao đổi số mũ công khai e và số mũ riêng d trong các đối tượng chính.

Nhưng tất cả điều này có vẻ như nó không có ý định được sử dụng/tấn công theo cách này. Vì vậy, tôi muốn hỏi ở đây về những hiểu lầm của tôi.

Ngoài ra, chỉ vì tò mò, tôi đã tạo một số phím (RSA.generate(2048)) và xem n, ed. Trong mọi trường hợp, nd là rất lớn trong khi e là trong mọi trường hợp hằng số (65537) (Tôi không mong đợi điều đó).

Tôi đoán từ tất cả những điều này mà tôi thực sự không nên chỉ trao đổi ed.

Vì vậy, tôi đoán tôi nên sử dụng một số phương pháp khác cho chữ ký như PKCS1_PSS.


Một số mã cho mã hóa/giải mã, nếu có ai quan tâm: (. binstruct là một mô-đun nhỏ mà có thể mã hóa/giải mã cây cấu trúc dữ liệu - tương tự như JSON/BSON)

def randomString(l): 
    import random 
    return ''.join(chr(random.randint(0, 0xFF)) for i in range(l)) 

def genkeypair(): 
    from Crypto.PublicKey import RSA 
    key = RSA.generate(2048) 
    pubkey = key.publickey().exportKey("DER") 
    privkey = key.exportKey("DER") 
    return (pubkey,privkey) 

def encrypt(v, rsapubkey): 
    from Crypto.PublicKey import RSA 
    rsakey = RSA.importKey(rsapubkey) 
    from Crypto.Cipher import PKCS1_OAEP 
    rsa = PKCS1_OAEP.new(rsakey) 
    import binstruct 
    from array import array 
    aeskey = randomString(32) 
    iv = randomString(16) 
    from Crypto.Cipher import AES 
    aes = AES.new(aeskey, AES.MODE_CBC, iv) 
    data = binstruct.varEncode(v) 
    data += array("B", (0,) * (-len(data) % 16)) 
    out = binstruct.strEncode(rsa.encrypt(aeskey + iv)) 
    out += array("B", aes.encrypt(data)) 
    return out 

def decrypt(stream, rsaprivkey): 
    from array import array 
    from StringIO import StringIO 
    if isinstance(stream, array): stream = stream.tostring() 
    if isinstance(stream, str): stream = StringIO(stream) 
    from Crypto.PublicKey import RSA 
    rsakey = RSA.importKey(rsaprivkey) 
    from Crypto.Cipher import PKCS1_OAEP 
    rsa = PKCS1_OAEP.new(rsakey) 
    import binstruct 
    aesdata = binstruct.strDecode(stream) 
    aesdata = rsa.decrypt(aesdata) 
    aeskey = aesdata[0:32] 
    iv = aesdata[32:] 
    from Crypto.Cipher import AES 
    aes = AES.new(aeskey, AES.MODE_CBC, iv) 
    class Stream: 
     buffer = [] 
     def read1(self): 
      if len(self.buffer) == 0: 
       nextIn = stream.read(16) 
       self.buffer += list(aes.decrypt(nextIn)) 
      return self.buffer.pop(0) 
     def read(self, n): 
      return "".join([self.read1() for i in range(n)]) 
    v = binstruct.varDecode(Stream()) 
    return v 

Đó là nơi tôi nghĩ tôi cũng có thể sử dụng encrypt bằng khóa riêng và decrypt bằng khóa công khai.


Việc thực hiện cuối cùng với (hy vọng) ký/xác thực chính xác có thể được tìm thấy here in binstruct.

+0

"PyCrypto than phiền khi tôi cố gắng giải mã bằng khóa công khai". Vui lòng cụ thể hơn và vui lòng hiển thị mã của bạn. –

+0

@GregS: Nó tăng 'TypeError (" Không có khóa riêng ")' trong '_RSAKey._decrypt'. Như bạn có thể thấy từ mã được liên kết. Đó là những gì tôi đã nói. Có vẻ như nó cần khóa riêng trong giải mã. – Albert

+0

Nếu bạn chỉ có kiến ​​thức thô sơ về mật mã, nó không làm gì để sử dụng API theo cách mà nó không được sử dụng. Tôi đã có 10 năm kinh nghiệm và thậm chí tôi khá cẩn thận khi tôi sử dụng các thư viện mật mã theo những cách mà tôi không được phép - và tôi cố gắng tránh làm như vậy bất cứ nơi nào có thể. –

Trả lời

15

Hiểu biết chung của bạn về trao đổi vai trò của khóa công khai và khóa riêng tư là chính xác. Cuối cùng, RSA dựa trên thực tế là

m^(ed) congruent m (mod n) 

gì thường được mang tên mã hóa RSA thường hoạt động

m^e mod n, 

nâng nhắn với sức mạnh e-thứ trong đó e là chìa khóa công cộng .

Decryption là sau đó

(m^e)^d mod n, 

nâng nhắn được mã hóa với sức mạnh d-ngày với d là khóa riêng. Bây giờ vì các quy tắc của lũy thừa và thực tế là nhân là giao hoán (những vẫn giữ trong số học modula), chúng tôi có mà

m congruent (m^e)^d congruent m^(ed) congruent m^(de) congruent (m^d)^e, 

và do đó bạn sẽ có được kết quả tương tự nếu bạn áp dụng các hoạt động theo thứ tự ngược lại.

Bạn có quyền giả định rằng sự đảo ngược dẫn đến chữ ký số, vì mọi người có thể xác minh ("giải mã") chữ ký với khóa công khai e, vì vậy thư chỉ được xác thực nếu nó được "mã hóa" (đã ký) bằng khóa riêng tương ứng d.

Khi nó quay ra, PyCrypto chỉ cố gắng ngăn cản bạn nhầm lẫn với nhau ở đây, OpenSSL hoặc Ruby OpenSSL cho phép bạn for example thực hiện cả hai: public_encrypt/public_decrypt và private_encrypt/private_decrypt.

Rất nhiều lý thuyết, bây giờ là lý do tại sao có lý do chính đáng để không cho phép bạn sử dụng chúng thay thế cho nhau. Những gì tôi vừa mô tả thường được gọi là "sách giáo khoa RSA" và nó vẫn còn xa mới được an toàn. Những điều bổ sung cần được quan tâm để làm cho kết quả có thể sử dụng được trong thực tế. Và đó là lý do tại sao có một số signature package chuyên dụng trong PyCrypto - điều này có hiệu quả với những gì bạn mô tả, nhưng cũng bổ sung cho những điều tôi đã đề cập. Mặc dù chúng tôi hiểu rõ cách thức hoạt động của những thứ này, chúng tôi luôn sử dụng các gói như vậy trong thực tế vì chúng đã tạo và sửa những lỗi mà chúng tôi có thể giới thiệu khi tự làm.

Vì sao e luôn là 65537. Nó thực sự không phải là một giá trị cố định, nhưng nó thường được chọn là một số rất nhỏ với số ít nhất trong biểu diễn nhị phân của nó càng tốt (65537 là 10001) . Trong quá khứ, e = 3 hoặc e = 17 cũng được chọn, nhưng được coi là không an toàn trong thực tế bởi vì chúng có thể bị tấn công bằng cách lấy gốc thứ 3 hoặc thứ 17 của bản mã. Nếu e = 3 và m = 3, thì 3^3 là 27, và không cần thiên tài để tìm ra rằng m là 3 cho rằng bản mã là 27, bất kể mô đun n (thường lớn hơn nhiều). Vì vậy, nguy hiểm nằm trong thực tế là bản mã, ngay cả sau khi lũy thừa, không vượt qua "ranh giới modulus" và do đó cho phép chúng ta đơn giản lấy gốc e thứ để đến thông điệp gốc. Với moduli điển hình là 1024 - 4096 bit, đây không còn là vấn đề với e = 65537 nữa.

Một số ít trong biểu diễn nhị phân cũng tốt để tính toán nhanh^^. Mô đun lũy thừa thường được thực hiện bằng cách sử dụng thuật toán Multiply and Square và hiệu suất tốt nhất cho các điện tử nhỏ với số ít. Tại sao nó được chọn theo cách này và không phải là cách khác tròn, ví dụ như có một d nhỏ với số ít của 1? Vâng cho người mới bắt đầu, d sẽ dễ dàng hơn để đoán theo cách đó. Lợi thế thứ hai là với chữ ký số, bạn thường ký một tài liệu một lần nhưng xác minh nó thường xuyên. Điều này có nghĩa là m^d được thực hiện một lần nhưng m^e thường xuyên, vì vậy bạn có nhiệm vụ chung thực hiện tốt nhất trong khi nhiệm vụ hiếm hoi được phép thực hiện kém.

Edit:

Bạn hỏi liệu tôi tiếp tục có thể giải thích những gì chương trình như RSA-PSS làm để được an toàn.

Khi so sánh những gì OAEP thực hiện để mã hóa và PSS làm gì cho chữ ký, cả hai trông khá giống nhau. Và trên thực tế, cả hai đều giới thiệu ngẫu nhiên trong quá trình, cho phép bảo mật có thể chứng minh là OAEPPSS theo các giả định nhất định. Tôi cũng tìm thấy điều này paper là hữu ích. An ninh có thể cung cấp là một lợi thế lớn so với mã hóa và chữ ký PKCS 1.5 của trường học cũ, có thể được chứng minh là không an toàn theo các giả định tương tự (điểm chính: không có sơ đồ xác định có thể, ngẫu nhiên là cần thiết). Một sự khác biệt rõ ràng giữa chữ ký được đề xuất và các lược đồ mã hóa là các lược đồ chữ ký luôn ủy thác thông điệp được ký để được băm trước. Điều này có ý nghĩa không chỉ đối với hiệu quả, nhưng nó cũng ngăn chặn một số cuộc tấn công mà nếu không sẽ là có thể. Và tôi đoán điều đó dẫn đến ý chính lý do tại sao chúng ta nên luôn sử dụng các lược đồ chữ ký cho chữ ký và lược đồ mã hóa để mã hóa: các đề án được đề xuất đi kèm với các chứng minh bảo mật đính kèm.

Các nhà mật mã phát minh ra những đề án đó để làm cho cuộc sống của chúng ta trở nên dễ dàng hơn - chúng cung cấp cho chúng ta những công cụ lý tưởng cho phép không lạm dụng hoặc lạm dụng bằng cách giảm số lượng tùy chọn ở mức tối thiểu. Ví dụ, ngay cả khi bạn đã có kế hoạch chữ ký tốt bằng cách sử dụng RSA-OAEP, ai đó sử dụng nó có thể không biết tại sao họ nên băm thông điệp của họ trước khi áp dụng chữ ký. Đó là loại lạm dụng thậm chí không phải là một khả năng với RSA-PSS.

Bạn cũng đã hỏi về một số tài liệu đọc tốt. Mặc dù đây là một chủ đề rất chủ quan, tôi thật sự rất thích những:

Phía thực hiện:

  • Applied Cryptography - vẫn còn là một cổ điển và đáng đọc. Một số người bảo mật nói rằng điều đó nguy hiểm vì nó khiến mọi người tin rằng họ biết đủ để viết mật mã của riêng mình. Nhưng tôi đoán chúng ta đều là những người trưởng thành, phải không? Vẫn còn tuyệt vời để có được cảm giác về "những gì ngoài kia"

  • Cryptography Engineering - Có một số lời khuyên thiết thực và cũng đề cập đến việc cẩn trọng khi triển khai mã mật mã.

  • Handbook of Applied Cryptography - Hoàn toàn miễn phí và vẫn có nhiều lời khuyên tốt, đặc biệt liên quan đến triển khai.

Phía lý thuyết:

  • Modern Cryptography - Đó là một lai giữa lý thuyết và thực hành và có rất nhiều cái nhìn sâu sắc như thế nào điều này có thể đi sai trong thực tế.

  • Cryptography - Theory and Practice - đây là công cụ đổi trò chơi cho tôi, tôi yêu thích cuốn sách này. Nếu bạn chỉ đọc một cuốn sách, hãy để nó là một cuốn sách này, hãy để nó là một trong những cuốn sách này, hãy để nó là một trong số này :)

  • Introduction to Modern Cryptography - thực hiện một giải pháp tuyệt vời để giải thích

  • Foundations of Cryptography I&II - nếu sau cuốn sách trước đó bạn vẫn không thể có đủ lý thuyết về chức năng một chiều và bạn bè, đây là cuốn sách của bạn. Rất kỹ thuật.

an ninh không chỉ là mật mã:

  • Security engineering - có rất nhiều ví dụ như thế nào nguyên tắc âm thanh có thể đi sai trong thực tế

  • Information Security - Tương tự như kỹ thuật an ninh, minh họa bảo mật trong một phạm vi rộng hơn chỉ là mật mã.

Bên cạnh đó, tôi cố gắng để theo kịp cập nhật bằng cách đọc bài báo gần đây về các cuộc tấn công mới, công nghệ vv Tôi tìm thấy r/netsec rất hữu ích, cũng như các nhà nghiên cứu và các học viên trên Twitter sau, họ gửi tài liệu thú vị thường xuyên .

Cuối cùng, nếu bạn có thời gian, hãy tham gia các khóa học Mật mã trên Coursera và Udacity! Tôi nghĩ rằng họ sẽ bắt đầu lại trong vài tuần tới, họ thực sự tuyệt vời, tôi chắc chắn bạn sẽ không hối tiếc. Họ đã có rất nhiều bài tập thực hành rất thú vị và minh họa độc đáo các cách khác nhau để tấn công triển khai mã hóa.

+1

Cảm ơn, rất hữu ích! - "Những thứ khác cần phải được chăm sóc [..]. [Gói chữ ký] bổ sung chăm sóc những thứ tôi đã đề cập". Tôi nghĩ rằng bạn đã không đề cập đến những điều đó một cách rõ ràng hoặc tôi đã không nhận được chúng. Điều gì bổ sung? Esp., Tại sao lại sử dụng RSASSA-PSS chứ không phải RSAES-OAEP (mã hóa bằng khóa riêng) cho chữ ký? - Bạn có thể giới thiệu thêm một số nguồn đọc về cách lấy từ một số sách giáo khoa lý thuyết RSA để sử dụng thực tế? (Bởi vì ngay cả đối với hầu hết các thư viện, tôi chủ yếu chỉ nhìn thấy các ví dụ tầm thường.) – Albert

+0

@Albert Tôi đã cập nhật câu trả lời của mình, hy vọng điều đó sẽ giúp ích? – emboss

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