it-swarm-vi.com

Kỹ thuật viết thuật toán mã hóa (dành riêng cho sử dụng cá nhân)

Tôi muốn mở đầu câu hỏi này bằng cách nói rằng tôi hoàn toàn hiểu được sự nguy hiểm của việc viết thuật toán mã hóa của riêng bạn và tôi sẽ không bao giờ sử dụng mã hóa tự chế để bảo mật dữ liệu của bất kỳ ai trừ chính tôi.

Hôm nay tôi được giao một dự án học kỳ khoa học máy tính tập hợp mọi thứ chúng ta đã học vào một chương trình. Một phần chức năng của chương trình này là nó có thể mã hóa và giải mã Chuỗi. Chúng ta phải tự viết các phương thức mã hóa này, vì vậy chúng ta không thể sử dụng bất kỳ thứ gì được tích hợp vào ngôn ngữ mà chúng ta đang sử dụng (Java). Cuối cùng, chúng ta cần tránh mọi thứ sử dụng khóa để mã hóa.

Bây giờ, sau khi nói chuyện với một số bạn cùng lớp của tôi, có vẻ như hầu hết mọi người đang sử dụng ROT13 hoặc một phương pháp tương tự khác. Bởi vì tôi là người vượt trội và vì tôi không muốn giống như mọi người khác, tôi muốn thiết kế phương pháp mã hóa của riêng mình. Tuy nhiên, tôi hơi lạc lõng khi bắt đầu từ đâu. Vì vậy, những kỹ thuật cơ bản hoặc nâng cao là gì để mã hóa?

18
Josh

Nếu bạn thường quan tâm đến mật mã ngoài dự án của bạn :

Nó phụ thuộc vào loại mã hóa bạn muốn làm. Hãy cẩn thận: câu trả lời này chỉ là về việc chỉ cho bạn đi đúng hướng lý thuyết. Tôi đặc biệt khuyên bạn nên đọc thật nhiều trước khi nhảy vào - bạn càng đọc nhiều bạn sẽ càng hiểu các mật mã trước đó đã bị hỏng và không mắc phải những lỗi tương tự.

Khóa công khai

Để vận hành một hệ thống khóa công khai, bạn cần một Hàm bẫy . Thật không may, lời khuyên trên wikipedia khá chính xác:

Một số lớp chức năng đã được đề xuất và rõ ràng là các hàm Bẫy khó tìm thấy hơn so với suy nghĩ ban đầu

Các chức năng bẫy là khá khó khăn; Hoán vị bẫy (trong đó các bộ đầu ra và đầu vào của các chức năng là như nhau và do đó chức năng "hoán vị" đầu vào bên trong bộ) thậm chí còn khó hơn. Nói một cách đơn giản, vấn đề nhân tố chính và vấn đề logarit rời rạc là hai "vấn đề lớn". Rất có thể trong lĩnh vực này, sử dụng một phương thức hiện có sẽ là cách tiếp cận dễ dàng nhất.

Khóa đối xứng

Các thuật toán khóa đối xứng có thể đảo ngược có chủ ý, nhưng không có một trong các đầu vào (khóa) được thiết kế để rất khó đảo ngược. Ý tưởng cơ bản là nguyên tắc nhầm lẫn/khuếch tán . Các kỹ thuật phổ biến trong mật mã hiện đại bao gồm mạng hoán vị thay thếmạng Feistel . Bạn cũng nên xem xét việc đọc lên chặn các chế độ hoạt động mật mã .

Phải, tuyệt, tôi nên bắt đầu từ đâu?

Bằng cách đọc - càng nhiều càng tốt. Tôi không thích lời khuyên tiêu chuẩn "không thiết kế tiền điện tử của riêng bạn". Tôi nghĩ mọi người nên thử nếu họ muốn. Nhưng tôi không thể nhấn mạnh đủ mức độ khó để làm đúng. Vì bạn đã giới hạn thời gian cho dự án của mình, một kỹ thuật có thể là sử dụng một ví dụ đơn giản về mật mã hiện có, vì vậy:

Dành cho dự án của bạn

Là một bài tập giáo dục RC4 rất dễ thực hiện. Ngày xưa (cách đây không lâu), điều này đã được sử dụng để bảo vệ lưu lượng SSL/WEP - đôi khi nó vẫn được sử dụng, vì vậy bạn sẽ sử dụng một mật mã thực sự. Nó có một số vấn đề bảo mật - hiểu những điều này cũng sẽ giúp bạn cho việc giáo dục tiền điện tử nói chung. Tuy nhiên, vì yêu cầu của bạn là bảo mật kém tuyệt đối và học hỏi nhiều hơn, tôi đã nghĩ rằng nó sẽ là lý tưởng.

Nếu bạn cảm thấy khá tham vọng và hiểu rõ ngôn ngữ của mình, AES cũng không khó thực hiện ở chế độ ECB. Trin-197 khá dễ đọc và thường giải thích thuật toán theo cách khá dễ tiếp cận.

Bạn có quyền coi ROT13 là một ví dụ tồi. Ngay cả khi không biết phần bù của mỗi ký tự là 13 vị trí, giả sử bạn sử dụng ASCII, bạn chỉ cần thử từng phần trong số 127 (hoặc 255 cho phần mở rộng ASCII) của văn bản mã hóa của mình cho đến khi phần bên phải giảm xuống Do đó, để giải mã nó là khá nhỏ, thậm chí không có chìa khóa.

15
user2213

Bạn phải tránh bất cứ điều gì sử dụng một chìa khóa? Cá nhân, tôi không thể thấy cách bạn có thể gọi thuật toán là "mã hóa" nếu nó không sử dụng khóa.

Bạn có thể xem xét việc tự thực hiện DES Đơn giản hóa. Đúng như tên gọi, Simplified DES (hoặc S-DES) là phiên bản đơn giản hóa rất nhiều của DES. Nó sử dụng khóa 10 bit và đủ đơn giản để xử lý bằng bút chì và giấy.

Bài viết này là lần truy cập đầu tiên của Google cho "Đơn giản hóa DES". Ngoài ra còn có một trình giả lập trực quan tại http://edipermadi.wordpress.com/2008/01/12/simplified-des-simulator/ .

8
Jonathan

Tôi không muốn làm hỏng cuộc vui của bạn, nhưng bạn muốn nghĩ về những điều sau đây:

  1. Điều gì, về bản chất, là mã hóa, dù sao? Các thuộc tính của những thứ mã hóa và giải mã là gì và tại sao chúng ta làm điều đó như một xã hội? Bạn muốn nghĩ về các đặc điểm cũng như quá trình.
  2. Chìa khóa là gì? Dựa trên nghiên cứu của bạn, bạn có thể muốn yêu cầu làm rõ điểm này từ người hướng dẫn của bạn.
  3. Tạo một hệ thống phân loại của tất cả các họ kỹ thuật mã hóa. Bằng cách thực hiện nghiên cứu này, bạn có thể tìm thấy một hoặc hai câu trả lời thú vị.

Đây là một dự án dựa trên học kỳ, vì vậy đây không phải là điều bạn có thể (hoặc nên) trả lời qua đêm. Bản thân mã có thể chỉ mất một hoặc hai ngày. Việc học thực sự là tìm kiếm các giải pháp dựa trên các ràng buộc nhất định.

4
logicalscope

Bạn nên đọc Cẩm nang áp dụng Crypgoraphy . Cuốn sách này còn được gọi là "Cẩm nang". Nó miễn phí, và được viết tốt. Tuy nhiên Chương 2, "Bối cảnh toán học" khá cứng nhắc, hầu hết các khái niệm này không được dạy tại trường đại học công lập địa phương của tôi (tôi đã xem xét).

2
rook

Nếu bạn muốn xem một phiên bản đơn giản hóa của "sự nhầm lẫn" và "khuếch tán" phức tạp, William Stallings đã viết một bản xuất sắc Đơn giản hóa DES triển khai .

Nó đủ dễ để tôi vẽ nó ra (và thực hiện các chuyển vị) trên giấy vẽ đồ thị. Nhưng nó sẽ đưa bạn qua tất cả các hàm cơ bản DES sử dụng và đưa bạn qua một vòng của quy trình giải mã mã hóa.

2
Joseph Kern

Tùy thuộc vào các ràng buộc đặt vào bạn, bạn thực sự có thể tạo ra một cách cực kỳ khó để bẻ khóa mã hóa một cách hợp lý dễ dàng - mã hóa này có những sai sót thực tế khiến nó không thể sử dụng được trong thế giới thực, nhưng bạn nên nhét ROT13, người dùng Caesar, v.v. bạn sẽ tạo ra một hệ thống mã hóa entropy, giúp bạn tạo ra một miếng đệm một lần

Viết cho mình một cái gì đó để đọc tất cả các tệp trên ổ đĩa của bạn - điều này khá dễ dàng, google về việc quét thư mục đệ quy phân cấp, mở tất cả các tệp thô/nhị phân và hút nội dung của chúng

Khi bạn bắt đầu truyền phát trong mỗi luồng byte, hãy tạo cho mình một tệp chính nơi bạn tìm kiếm một chuỗi lặp lại (tôi sẽ gọi chúng là các chuỗi từ bây giờ, vì đó là những gì chúng là, chúng không phải là chuỗi văn bản) trong đầu vào - bạn cần tạo một thuật toán theo thời gian, ưu tiên các chuỗi kết hợp dài nhất có thể nhưng có thể phân chia đệ quy đầu vào thành các chuỗi nhỏ hơn - nếu bạn nhìn vào http://en.wikipedia.org/wiki/Huffman_coding bạn sẽ thấy một thuật toán cụ thể để thực hiện điều này nhưng bạn không cần phải đi xa đến thế - nhưng việc triển khai có thể sẽ mang lại các đoạn mã sẽ đơn giản hóa cuộc sống của bạn.

Bây giờ, để mã hóa thứ gì đó, hãy lấy chuỗi đầu vào và áp dụng cùng một thao tác, tìm chuỗi con phù hợp với độ dài dài nhất trong tệp chính và thay thế chuỗi đầu vào bằng phần bù và độ dài của chuỗi con phù hợp trong tệp chính - lưu ý điều này sẽ khớp với bất kỳ chuỗi, bởi vì vào cuối ngày, bạn sẽ tìm lại các bit đơn lẻ Một bảo vệ bạn sẽ cần sử dụng là bạn phải quay vòng tập hợp tất cả các chuỗi khớp trước khi bạn bắt đầu sử dụng lại các chỉ mục giống nhau - hãy tưởng tượng một tệp chính trong đó bạn có xen kẽ 1 và 0 và bạn chỉ có thể khớp các đầu vào ở cấp độ bit (về mặt kỹ thuật là không thể nhưng với tôi) - nếu bạn nhận được chuỗi 5 1 giây, bạn sẽ mã hóa thành 1: 1,3: 1,5 : 1,7: 1,9: 1 (vâng, một lỗ hổng là mã hóa này có thể trở nên kém hiệu quả trong một số trường hợp nhất định) (nb - nếu bạn mã hóa bit, bạn sẽ làm yếu mã - thêm điểm nếu bạn chỉ di chuyển bù vào thông điệp, nhưng đó là một chiến lược ánh xạ đa chiều khó chịu nằm ngoài phạm vi của bài đăng này)

Theo dõi số lượng các chỉ số được sử dụng lại - mục tiêu của bạn là có một bảng tổng thể đủ lớn để điều này không bao giờ xảy ra - nếu điều này xảy ra và bạn chỉ mã hóa một thông điệp thì chắc chắn vũ trụ sẽ chết vì nóng trước khi mã có thể đã bẻ khóa càng nhiều tin nhắn mà bạn mã hóa KHI CHỈ ĐƯỢC TÌM HIỂU, mã của bạn càng bị bắt buộc (phân tích ngôn ngữ, phân tích mẫu, v.v.) Bây giờ đây là cách bắt - để sử dụng mã này với một bên khác - bạn cần phải lấy cho họ một bản sao của bảng chính - bạn chỉ nên thực hiện việc này trực tiếp, bạn phải luôn giữ phương tiện truyền tải dưới sự kiểm soát của mình và bạn nên hủy nó khi quá trình chuyển hoàn tất - và nếu bất kỳ máy nào có bảng chính được kích hoạt, mã của bạn sẽ được nướng - cho đến lúc đó, nó khá khó khăn

Chúc vui vẻ

1
Mark Mullin

Đối với mã hóa hai chiều, hầu hết các thuật toán sử dụng toán tử x hoặc toán tử, so sánh mã nhị phân của khóa và dữ liệu nhị phân của đầu vào, điều này có thể không phù hợp với bạn khi đó, vì bạn không thể sử dụng khóa ... tuy nhiên, đây là làm thế nào nó hoạt động:

Dữ liệu đầu vào: 10011101101001 Khóa: 123 = 1111011

Khóa này nhỏ hơn đầu vào, vì vậy nó cần được lặp lại:

Dữ liệu đầu vào: 10011101101001 Khóa: 123 = 11110111111011

(in Java sử dụng một biến để đếm trong mỗi hoặc một vòng lặp while máng tất cả các bit của dữ liệu đầu vào ...) Bây giờ sử dụng x hoặc gốc để tạo kết quả được mã hóa (hai cách băm) lặp qua từng bit trong dữ liệu đầu vào và so sánh nó với bit tương ứng trong khóa, nếu giống hệt nhau, thêm 0 vào kết quả, nếu không, thêm 1 vào kết quả ... Kết quả sẽ là:

Dữ liệu đầu vào: 10011101101001 Khóa: 123 = 11110111111011 Kết quả = 01101010010010

Để giải mã dữ liệu, chỉ cần chạy máng dữ liệu được mã hóa:

Dữ liệu đầu vào: 01101010010010 Khóa: 123 = 11110111111011 Kết quả = 10011101101001

Lý tưởng nhất là bạn sẽ sử dụng hàm băm như sha, md5, ripemd, v.v ... để tạo khóa, sau đó chuyển nó thành nhị phân ... nếu bạn không thể sử dụng thuật toán tiền tố, bạn có thể tạo thuật toán của riêng mình để tạo khóa được so sánh ... chỉ cần làm cho tất cả các bit trong đầu vào phụ thuộc lẫn nhau để tạo ra kết quả ... ví dụ:

mật khẩu: abcdefghi abc = 123456789 (a = 1, b = 2, c = 3 vv ...)

bây giờ lặp từng bit (chữ số) và thêm chúng cùng với một bộ đếm, ví dụ: Count = 0 result = "" foreach chữ số trong mật khẩu do {result = result & (chữ số + result [Count-1]) * Count) Count = Count +1}

kết quả = (1 + 0) * 1 = 1 (2 + 1) * 2 = 6 (3 + 2) * 3 = 15 (4 + 3) * 4 = 28 (5 + 4) * 5 = 45 (6+ 5) * 6 = 66 (7 + 6) * 7 = 91 (8 + 7) * 8 = 120 (9 + 8) * 9 = 153

key result = 16152845669120153 Binary: 111001011000101110110101110100001110000011100010011001 (Đây là một ví dụ rất kém ... bạn nên nghĩ rằng một thuật toán tốt ... một trong đó hai đầu vào bắt đầu kết hợp và tạo thành thứ ba kết quả của sự kết hợp đầu tiên để tạo ra kết quả cuối cùng ...)

nhưng một lần nữa, nếu bạn không thể sử dụng khóa, bạn không thể sử dụng ...

1
Daniel V

Kiểm tra lớp Crypto I từ Đại học Stanford trên coursera. Nó phá vỡ luồng và chặn mật mã cũng như mã hóa khóa công khai. Bạn sẽ được thông báo nhiều hơn nếu bạn chỉ xem một vài bài giảng đầu tiên. Ngoài ra, khóa học cũng bao gồm các lỗ hổng và phương pháp phá vỡ việc triển khai tiền điện tử.

0
Andrew