Professional Documents
Culture Documents
Nhóm 6 - ATBMTT
Nhóm 6 - ATBMTT
Đề tài:
Hà Nội, 2023
1
NHẬN XÉT CỦA GIẢNG VIÊN
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
.................................................................................................................................
MỤC LỤC
2
LỜI MỞ ĐẦU.....................................................................................................................7
CHƯƠNG 1. CỞ SỞ LÝ THUYẾT....................................................................................8
1.1.2 Các mối đe dọa đối với một hệ thống và các biện pháp ngăn chặn...............8
1.1.3 Mục tiêu chung của an toàn bảo mật thông tin..............................................9
1.2.5 Sơ đồ khối...................................................................................................13
3
2.1.2 Quy trình giải mã.........................................................................................26
2.2.1 Các modules sử dụng trong quá trình mã hóa và giải mã............................31
PHỤ LỤC..........................................................................................................................42
4
DANH MỤC HÌNH VẼ
Hình 1. 1 Chuẩn mã dữ liệu DES............................................................................11
Hình 1. 2 Sơ đồ khối chương trình DES.................................................................13
Hình 1. 3 Sơ đồ khối quá trình sinh khóa................................................................14
Hình 1. 4 Ngôn ngữ Java.........................................................................................16
5
DANH MỤC BẢNG
Bảng 1. Hoán vị IP.................................................................................................25
Bảng 2. Hoán vị IP-1..............................................................................................25
Bảng 3. Hoán vị PC-1.............................................................................................28
Bảng 4. Bảng dịch bit tại các vòng lặp DES..........................................................29
Bảng 5. Hoán vị PC-2.............................................................................................29
Bảng 6. Hàm mở rộng E.........................................................................................30
Bảng 7. 8 hộp S-Box..............................................................................................30
Bảng 8. Bảng hoán vị P..........................................................................................30
6
LỜI MỞ ĐẦU
Từ thời xa xưa con người đã quan tâm đến việc làm thế nào để bảo mật các
tài liệu quan trọng, đặc biệt là trong lĩnh vực quân sự, ngoại giao… Ngày nay với
sự ra đời của máy tính cũng như sự phát triển của lĩnh vực Công nghệ thông tin,
các tài liệu văn bản, giấy tờ quan trọng đều được số hóa và xử lý trên máy tính,
được truyền đi trong môi trường mà mặc định là không an toàn. Do đó yêu cầu về
việc có một cơ chế, giải pháp để bảo vệ sự an toàn và bí mật của các thông tin nhạy
cảm, quan trọng ngày càng trở nên cấp thiết, bảo mật thông tin chính là lĩnh vực
đảm bảo cho mục đích này.
Mã hóa thông tin là một mảng kiến thức quan trọng trong chương trình đào
tạo công nghệ thông tin, em muốn đi sâu vào một phương pháp mã hóa cụ thể để
cài đặt các hệ mã để mã hóa file, văn bản nên em chọn đề tài Phương pháp mã hóa
DES, đây là phương pháp làm tiền đề cho các phương pháp mã hóa tốt nhất hiện
nay.
Khi làm đồ án này, em muốn giới Thầy Cô và các bạn kiến thức tổng quan
về mã hóa, đồng thời trình bày về phương pháp mã hóa DES và quy trình bảo mật
thông tin của phương pháp mã hóa DES.
MỤC TIÊU:
Đề tài giới thiệu về hệ thống mã hóa và đi sâu nghiên cứu phương pháp mã hóa
DES, đưa ra hướng dẫn cài đặt chương trình mã hóa văn bản, file văn bản một
cách đơn giản, hiệu quả.
PHẠM VI ĐỀ TÀI:
7
CHƯƠNG 1. CỞ SỞ LÝ THUYẾT
1.1 Tổng quan về an toàn và bảo mật thông tin
Thông tin là một bộ phần quan trọng và là tài sản thuộc quyền sở hữu của các
tổ chức.
Sự thiệt hại và lạm dụng thông tin không chỉ ảnh hưởng đến người sử dụng
hoặc các ứng dụng mà nó còn gây ra các hậu quả tai hại cho toàn bộ tổ chức
đó.
Thêm vào đó sự ra đời của Internet đã giúp cho việc truy cập thông tin ngày
càng trở nên dễ dàng hơn.
1.1.2 Các mối đe dọa đối với một hệ thống và các biện pháp ngăn chặn
8
Các biện pháp ngăn chặn:
Điều khiển thông qua phần mềm: dựa vào các cơ chế an toàn bảo mật của hệ
thống nền (hệ điều hành), các thuật toán mật mã học
Điều khiển thông qua phần cứng: các cơ chế bảo mật, các thuật toán mật mã
học được cứng hóa để sử dụng
Điều khiển thông qua các chính sách của tổ chức: ban hành các qui định của tổ
chức nhằm đảm bảo tính an toàn bảo mật của hệ thống.
1.1.3 Mục tiêu chung của an toàn bảo mật thông tin
Tính bí mật (Confidentiality): Đảm bảo rằng thông tin không bị truy cập bất
hợp pháp. Thuật ngữ privacy thường được sử dụng khi dữ liệu được bảo vệ có
liên quan tới các thông tin mang tính cá nhân.
Tính toàn vẹn (Integrity): Đảm bảo rằng thông tin không bị sửa đổi bất hợp
pháp.
Tính sẵn dùng (availability): Tài sản luôn sẵn sàng được sử dụng bởi nhưng
người có thẩm quyền
Viết mật mã: đảm bảo tính bí mật của thông tin truyền thông
Xác thực quyền: được sử dụng để xác minh, nhận dạng quyền hạn của các
thành viên tham gia.
Các khoá giống nhau được sử dụng cho việc mã hoá và giải mã
Thuật toán mã hoá sử dụng khoá đối xứng thường được biết đến là DES (Data
Encryption Standard)
9
Các thuật toán mã hoá đối xứng khác được biết đến như: -Triple DES, DESX,
GDES, RDES - 168 bit key -RC2, RC4, RC5 - variable length up to 2048 bits -
IDEA - basis of PGP - 128 bit key.
Các khoá dùng cho mã hoá và giải mã khác nhau nhưng cùng một mẫu và là
cặp đôi duy nhất (khoá private/ public).
Khoá private chỉ được biết đến bởi người gửi.
Khoá public được biết đến bởi nhiều người hơn nó được sử dụng bởi những
nhóm người đáng tin cậy đã được xác thực.
Ngày 13/5/1973 ủy ban quốc gia về tiêu chuẩn của Mỹ công bố yêu cầu về hệ
mật mã áp dụng cho toàn quốc. Điều này đã đặt nền móng cho chuẩn mã hóa
dữ liệu, hay là DES.
Lúc đầu Des được công ty IBM phát triển từ hệ mã Lucifer, công bố vào năm
1975. –
Sau đó Des được xem như là chuẩn mã hóa dữ liệu cho các ứng dụng.
10
1.2.3 Phương pháp bảo mật
DES là thuật toán mã hóa với input là khối 64 bit, output cũng là khối 64 bit. Khóa
mã hóa có độ dài 56 bit, thực ra chính xác hơn phải là 64 bit với các bit ở vị trí chia
hết cho 8 có thể sử dụng là các bit kiểm tra tính chẵn lẻ. Số khóa của không gian
khóa K là 256
Bản rõ 64 bit sẽ được sử dụng chia thành 2 nữa L 0 và R0. Các vòng có chức năng
giống nhau, nhận input là Li-1 và Ri-1 từ vòng truớc và sinh ra output là các xâu 32 bit
Li và Ri như sau:
Li=Ri-1;
Trong đó:
- là ký hiệu của phép tuyển loại trừ (XOR) của hai xâu bit theo modulo 2.
- E là hoán vị mở rộng ánh xạ R i-1 từ 32 bit thành 48 bit (đôi khi tất cả các bit sẽ
được sử dụng hoặc một bit sẽ được sử dụng hai lần)
Một hoán vị khởi đầu (IP) được sử dụng cho vòng đầu tiên, sau vòng cuối cùng
nửa trái và phải sẽ được đổi cho nhau và xâu cuối cùng kết quả sẽ được hoán vị lần
cuối bởi hoán vị ngược của IP (IP-1).
Quá trình giải mã diễn ra tương tự nhưng với các khóa con ứng dụng vào các
vòng theo thứ tự ngược lại.
11
1.2.4 Ưu nhược điểm
1.2.4.1 Ưu điểm
Nó có thể triển khai trên thiết bị điện tử có kích thước nhỏ
Tính bù
Nếu ta ký hiệu u là phần bù của u (ví dụ : 0100101) thì des có tính chất sau
Khóa yếu
Khóa yếu là các khóa mà theo thuật toán sinh khóa con thì tất cả 16 khóa con
đều như nhàu: K1=K2=…=K16
Điểu đó khiến cho việc mã hóa và giải mã đối với khóa yếu là giống hệt nhau.
Đồng thời còn có 6 cặp khóa nửa yếu (semi-weak key) khác với thuộc tính như
sau : y= DES(x,k1) và y=DES(x,k2)
Nghĩa là với 2 khóa khác nhau nhưng mã hóa cùng một bản mã từ cùng một bản
rõ
Với 64 bit khối bản rõ có thể được ánh xạ lên tất cả các vị trí của khối 64 bit
khối bản mã trong 264 cách. Trong thuật toán DES, với 56 bit khóa có thể cho
chúng ta 256 (khoảng 1017 ) vị trí ánh xạ. Với việc đa mã hóa thì không gian ánh
xạ còn lớn hơn. Tuy nhiên điều này chỉ đúng nếu việc mã hóa DES là không cấu
trúc.
12
DES có 256 = 1017 khóa. Nếu chúng ta biết được một cặp “tin/mã” thì chúng ta có
thể thử tất cả 1017 khả năng này để tìm ra khóa cho kết quả khớp nhất.
1.2.5 Sơ đồ khối
13
Hình 1. 3 Sơ đồ khối quá trình sinh khóa
14
1.3 Ứng dụng của DES
DES và 3DES được ứng dụng rộng rãi trong các lĩnh vực mật mã, xác thực, an
toàn thông tin... Năm 2002 tiêu chuẩn mã hóa tiên tiến AES (Advanced Encryption
Standard) được đề xuất thay thế cho tiêu chuẩn DES và 3DES, song vẫn có nhiều
lĩnh vực áp dụng sử dụng DES, 3DES sau này. Trong Thông tư số 01/2011/TT-
BTTTT ngày 04/01/2011 của Bộ Thông tin và Truyền thông Công bố Danh mục
tiêu chuẩn kỹ thuật về ứng dụng công nghệ thông tin trong cơ quan nhà nước quy
định Khuyến nghị áp dụng tiêu chuẩn 3DES và được xếp vào nhóm Tiêu chuẩn
về an toàn thông tin.
Java là một ngôn ngữ lập trình hướng đối tượng (OOP) và dựa trên các lớp (class),
ban đầu được phát triển bởi Sun Microsystems do James Gosling khởi xướng và
phát hành vào năm 1995. Khác với phần lớn ngôn ngữ lập trình thông thường, thay
vì biên dịch mã nguồn thành mã máy hoặc thông dịch mã nguồn khi chạy, Java
được thiết kế để biên dịch mã nguồn thành bytecode, bytecode sau đó sẽ được môi
trường thực thi (runtime environment) chạy.
15
Hình 1. 4 Ngôn ngữ Java
Là một ngôn ngữ lập trình hướng đối tượng vì vậy Java cũng có 4 đặc điểm chung
sau đây:
Tính trừu tượng (Abstraction): là tiến trình xác định và nhóm các thuộc tính,
các hành động liên quan đến một thực thể đặc thù, xét trong mối tương quan
với ứng dụng đang phát triển.
Tính đa hình (Polymorphism): cho phép một phương thức có các tác động
khác nhau trên nhiều loại đối tượng khác nhau. Với tính đa hình, nếu cùng một
phương thức ứng dụng cho các đối tượng thuộc các lớp khác nhau thì nó đưa
đến những kết quả khác nhau. Bản chất của sự việc chính là phương thức này
bao gồm cùng một số lượng các tham số.
Tính kế thừa (Inheritance): điều này cho phép các đối tượng chia sẻ hay mở
rộng các đặc tính sẵn có mà không phải tiến hành định nghĩa lại.
Tính đóng gói (Encapsulation): là tiến trình che giấu việc thực thi những chi
tiết của một đối tượng đối với người sử dụng đối tượng ấy.
Ngoài ra Java còn có một số đặc điểm sau:
16
Đơn giản: Học Java thật sự dễ hơn nhiều so với C/C++, nếu ta đã quen với các
ngôn ngữ lập trình hướng đối tượng thì việc học Java sẽ dễ dàng hơn. Java trở
nên đơn giản hơn so với C/C++ do đã loại bỏ tính đa kế thừa và phép toán con
trỏ từ C/C++.
Bảo mật: Java hỗ trợ bảo mật rất tốt bởi các thuật toán mã hóa như mã hóa một
chiều (one way hashing) hoặc mã hóa công cộng (public key)…
Thông dịch: Java là một ngôn ngữ lập trình vừa biên dịch vừa thông dịch.
Chương trình nguồn viết bằng ngôn ngữ lập trình Java có đuôi *.java và được
biên dịch thành tập tin có đuôi *.class sau đó được trình thông dịch thông dịch
thành mã máy.
Đa luồng: Với tính năng đa luồng Java có thể viết chương trình có thể thực thi
nhiều task cùng một lúc. Tính năng này thường được sử dụng rất nhiều trong
lập trình game.
Hướng đối tượng: Hướng đối tượng trong Java tương tự như C++ nhưng Java
là một ngôn ngữ lập trình hướng đối tượng hoàn toàn. Tất cả mọi thứ đề cập
đến trong Java đều liên quan đến các đối tượng được định nghĩa trước, thậm
chí hàm chính của một chương trình viết bằng Java (đó là hàm main) cũng phải
đặt bên trong một lớp. Hướng đối tượng trong Java không có tính đa kế thừa
(multi inheritance) như trong C++ mà thay vào đó Java đưa ra khái niệm
interface để hỗ trợ tính đa kế thừa.
Hiệu suất cao: Nhờ vào trình thu gom rác (garbage collection), giải phóng bộ
nhớ đối với các đối tượng không được dùng đến.
Linh hoạt: Java được xem là linh hoạt hơn C/C ++ vì nó được thiết kế để thích
ứng với nhiều môi trường phát triển.
Hầu hết các nền tảng chéo kể từ khi nó được thiết kế cho nó và Sun tạo ra JRE
và JDK cho hầu hết các nền tảng.
Tất cả mọi thứ được truyền bằng tham chiếu ngoại trừ các loại giá trị, theo mặc
định.
17
Rõ ràng java 6 chạy (một số?) Công cụ nhanh hơn một chút so với c ++ (mã
kiểm tra được chuyển từ c ++ chạy nhanh hơn mặc dù phải làm những việc có
vẻ lãng phí!).
Chương trình được biên dịch và tối ưu hóa cho nền tảng, nếu cần?
Dễ dàng tạo nhiều luồng và ta có thể khai báo các chức năng được đồng bộ hóa
để chỉ một luồng có thể có trong một luồng (IIRC)
Ta có thể sử dụng Wait () và notifyAll () và thông báo () để tạm dừng các
luồng để chờ tín hiệu và đánh thức chúng lại.
Các IDE miễn phí khác nhau có sẵn trên tất cả các nền tảng, chẳng hạn như
Eclipse.
Nếu chương trình gặp sự cố, nó sẽ báo cho người dùng biết mã trong đó ở đâu
và tại sao, hiển thị dấu vết ngăn xếp bao gồm số dòng (nếu biểu tượng gỡ lỗi
được bật hoặc một cái gì đó tương tự) hoặc có thể được đổ vào tệp nhật ký lỗi.
Các chương trình có thể được đóng gói thành các tệp jar với các tệp dữ liệu
khác nhau trong các tệp jar khác nhau và được người dùng truy cập bằng Java
WebStart, sẽ tự động cập nhật chương trình và mọi tệp jar cần thiết khác lên
phiên bản mới nhất, chỉ tải xuống các tệp jar đã thay đổi.
Mạng dễ dàng hơn / nhiều nền tảng hơn c ++.
Các tệp được đọc và ghi dưới dạng big endian trên tất cả các nền tảng (là thứ tự
byte mạng) đảm bảo rằng giao tiếp giữa các chương trình java và tải tệp không
bao giờ yêu cầu hoán đổi thứ tự byte (trừ khi nói chuyện với chương trình
không phải java hoặc sử dụng tệp được viết bởi một ).
WebSoket là công nghệ hỗ trợ giao tiếp hai chiều giữa client và server bằng cách
sử dụng một TCP socket để tạo một kết nối hiệu quả và ít tốn kém. Mặc dù được
18
thiết kế để chuyên sử dụng cho các ứng dụng web, lập trình viên vẫn có thể đưa
chúng vào bất kì loại ứng dụng nào.
Để thực hiện kết nối, client phải gửi một WebSocket handshake request đến server.
Server sẽ gửi trả lại WebSocket handshake response như bên dưới:
Client request:
Để xác nhận việc kết nối, client sẽ gửi một giá trị Sec-WebSocket-Key được mã
hóa bằng Based64 đến server. Sau đó bên server sẽ thực hiện:
“x3JJHMbDL1EzLkh9GBhXDw==258EAFA5-E914-47DA-95CA-
C5AB0DC85B11″.
19
- Thực hiện mã hóa SHA-1 chuỗi trên để được:
“1d29ab734b0c9585240069a6e4e3e91b61da1969″.
“HSmrc0sMlYUkAGmm5OPpG2HaGWk=”.
Gửi response lại client kèm với giá trị Sec-WebSocket-Accept chính là chuỗi kết
quả vừa tạo ra.
Client sẽ kiểm tra status code (phải bằng 101) và Sec-WebSocket-Accept xem có
đúng với kết quả mong đợi không và thực hiện kết nối.
1.5.2.1 Ưu điểm
WebSockets cung cấp khả năng giao tiếp hai chiều mạnh mẽ, có độ trễ thấp
và dễ xử lý lỗi. Không cần phải có nhiều kết nối như phương pháp Comet
long-polling và cũng không có những nhược điểm như Comet streaming.
API cũng rất dễ sử dụng trực tiếp mà không cần bất kỳ các tầng bổ sung nào,
so với Comet, thường đòi hỏi một thư viện tốt để xử lý kết nối lại, thời gian
chờ timeout, các Ajax request (yêu cầu Ajax), các tin báo nhận và các dạng
truyền tải tùy chọn khác nhau (Ajax long-polling và jsonp polling).
WebSockets là một đặc tả mới của HTML5, nên nó vẫn chưa được tất cả các
trình duyệt hỗ trợ.
Không có phạm vi yêu cầu nào. Do WebSocket là một TCP socket chứ
không phải là HTTP request, nên không dễ sử dụng các dịch vụ có phạm vi-
yêu cầu, như SessionInViewFilter của Hibernate. Hibernate là một
framework kinh điển cung cấp một bộ lọc xung quanh một HTTP request.
Khi bắt đầu một request, nó sẽ thiết lập một contest (chứa các transaction và
liên kết JDBC) được ràng buộc với luồng request. Khi request đó kết thúc,
bộ lọc hủy bỏ contest này.
20
1.6 Cài đặt môi trường lập trình Java
Tải JDK để cài đặt môi trường Java. Ta sẽ tải tại trang theo đường link:
https://www.oracle.com/java/technologies/downloads/
21
CHƯƠNG 2. XÂY DỰNG CHƯƠNG TRÌNH MÃ HÓA VÀ GIẢI MÃ
MẬT MÃ DES BẰNG NGÔN NGỮ JAVA
DES là thuật toán mã hóa khối, nó xử lý từng khối thông tin của bản rõ có độ dài
xác định là 64 bit. Trước khi đi vào 16 chu trình chính, khối dữ liệu cần bảo mật
được “bẻ” ra từng khối 64 bit, và từng khối 64 bit này sẽ được lần lượt đưa vào 16
vòng mã hóa DES để thực hiện
Input: bản rõ M = m1m2 … m64, là một khối 64 bit, khóa 64 bit K = k1k2 . . . k64
( bao gồm cả 8 bit chẵn lẻ )
1. Sinh khóa con. Tính các khóa con theo thuật toán sinh khóa con
2. (L0,R0) IP (m1 m2 . . . m64) (sử dụng bản hoán vị IP để hoán vị các bit, kết quả
nhận được chia thành 2 nửa là L0, R0)
3. ( 16 vòng) for i= 1 to 16
Li=Ri-1;
Mở rộng Ri-1 = r1r2 . . . r32 từ 32 bit thành 48 bit bằng cách sử dụng hoán vị mở
rộng E.
T’ T Ki. Biểu diễn T’ như là các xâu gồm 8 ký tự 6 bit
T’ = ( B1, . . . ,B8 )
22
4. b1 b2 . . . b64 ( R16, L16) ( đổi vị trí các khối cuối cùng L16 , R16)
23
Hình 2. 1 Sơ đồ mã hóa DES
Giai đoạn 1:
Với bản rõ cho trước x, 1 xâu x' sẽ được tạo ra bằng cách hoán vị các bit của
x theo hoán vị ban đầu IP:
x'=IP(x)=L0 R0
24
IP:
Bảng 1. Hoán vị IP
58 50 42 34 26 18 10 02
60 52 44 36 28 20 12 04
62 54 46 38 30 22 14 06
64 56 48 40 32 24 16 08
57 49 41 33 25 17 09 01
59 51 43 35 27 19 11 03
61 53 45 37 29 21 13 05
63 55 47 39 31 23 15 07
Giai đoạn 2:
Tính toán 16 lần lập theo 1 hàm xác định. Ta sẽ tính LiRi (1≤ i ≤ 16) theo quy tắc:
Li=Ri-1
Ri = Li-1 f (Ri-1, Ki)
là toán tử Xor
Giai đoạn 3:
Áp dụng hoán vị ngược IP-1 cho xâu bit R16 L16 ta thu được bản mã y:
y = IP-1 (R16 L16). Chú ý vị trí của R16 và L16.
IP-1
25
40 8 48 16 56 24 64 32
39 7 47 15 55 23 63 31
38 6 46 14 54 22 62 30
37 5 45 13 53 21 61 29
36 4 44 12 52 20 60 28
35 3 43 11 51 19 59 27
34 2 42 10 50 18 58 26
33 1 41 9 49 17 57 25
Do là 1 thuật toán đối xứng nên quá trình giải mã và mã hóa cũng gần giống nhau
chỉ khác ở:
Li=Ri-1
Ri = Li-1 f (Ri-1, K16-i)
2.1.3 Hàm F
Biến 1:R là xâu bit có độ dài 32 bit, biến 2:K là xâu bit có độ dài 48 bit.Đầu ra của
f là xâu bit có độ dài 32 bit.
- Tính E ( Ri-1 ) Ki và viết kết quả thành 8 xâu 6 bit B1B2B3B4B5B6B7B8
- Đưa khối 8 bit Bi vào 8 bảng S1, S2, … .S8 ( được gọi là các hộp S-Box). Mỗi hộp
S-Box là một bảng 4*16 cố định có các cột từ 0 đến 15 và các hàng từ 0 đến 3. Với
mỗi xâu 6 bit Bi = b1b2b3b4b5b6, ta tính được Si ( B i) như sau: hai bit b1b6 xác định
hàng r trong trong hộp Si, bốn bit b2b3b4b5 xác định cột c trong hộp SI. Khi đó, Si (Bi
26
) sẽ xác định phần tử Ci=Si ( r,c), phần tử này viết dưới dạng nhị phân 4 bit. Như
vậy, 8 khối 6 bit Bi ( 1 i 8 ) sẽ cho ra 8 khối 4 bit Ci với ( 1 i 8 )
- Xâu bit C = C1C2C3C4C5C6C7C8 có độ dài 32 bit được hoán vị theo phép toán
hoán vị P (hộp P-Box). Kết quả P(C) sẽ là kết quả của hàm f( R i-1, Ki), và cũng
chính Ri cho vòng sau.
Hình 2. 4 Sơ đồ hàm F
- Mười sáu vòng lặp DES chạy cùng thuật toán như nhau nhưng với 16 khóa con
khác nhau. Các khóa con đều được sinh ra từ khóa chính của DES bằng một thuật
toán sinh khóa con.
27
Hình 2. 5 Sơ đồ tạo khóa con
PC-1
57 49 41 33 25 17 09
01 58 50 42 34 26 18
10 02 59 51 43 35 27
19 11 03 60 52 44 36
63 55 47 39 31 23 15
07 62 54 46 38 30 22
14 06 61 53 45 37 29
21 13 05 28 20 12
04
Ta chia PC-1 thành 2 phần: C0:28 bit đầu, D0:28 bit cuối
28
Mỗi phần sẽ được xử lý 1 cách độc lập.
Ci=LSi(Ci-1)
Di = LSi(Ci-1) với 1≤ i ≤ 16
+ LSi biểu diễn phép dịch bit vòng(cyclic shift) sang trái 1 hoặc 2 vị trí tuỳ thuộc
vào i. Cyclic shift sang trái 1 bit nếu i=1,2,9,16 hoặc sang trái 2 bit nếu i thuộc các vị
trí còn lại.
Ki=PC-2(CiDi).
+ PC-2 là hoán vị cố định sẽ hoán vị chuối CiDi 56 bit thành chuỗi 48 bit.
PC-2
14 17 11 24 01 05
03 28 15 06 21 10
23 19 12 04 26 08
16 07 27 20 13 02
41 52 31 37 47 55
30 40 51 45 33 48
44 49 39 56 34 53
46 42 50 36 29 32
Hàm mở rộng (E) sẻ tăng độ dài từ Ri từ 32 bit lên 48 bit bằng cách thay đổi
các thứ tự của các bit cũng như lặp lại các bit.
29
Bảng 6. Hàm mở rộng E
- Mỗi hàng trong mỗi hộp S là hoán vị của các số nguyên từ 0 đến 15
S1
14 04 13 01 02 15 11 08 03 10 06 12 05 9 0 07
00 15 07 04 14 02 13 01 10 06 12 11 09 05 3 08
04 01 14 08 13 06 02 11 15 12 09 07 03 10 5 00
15 12 08 02 4 09 01 07 05 11 03 14 10 00 6 13
…….
S8
13 02 08 04 06 15 11 01 10 09 03 14 05 00 12 07
01 15 13 08 10 03 07 04 12 05 06 11 00 14 09 02
07 11 04 01 09 12 14 02 00 06 10 13 15 03 05 08
02 01 14 07 04 10 08 13 15 12 09 00 03 05 06 11
Việc hoán vị này mang tính đơn ánh, nghĩa là một bit đầu vào sẽ cho một bit
ở đầu ra, không bit nào được sử dụng 2 lần hay bị bỏ qua. Hộp P-Box thực chất chỉ
là chức năng sắp xếp đơn thuần theo bảng sau:
30
2.2 Triển khai lập trình
31
}
subkeys[i] = PC2(cd);
}
Hàm Feistel
private static int feistel(int r, /* 48 bits */ long subkey)
{
// 1. expansion
long e = E(r);
// 2. key mixing
long x = e ^ subkey;
// 3. substitution
int dst = 0;
for (int i = 0; i < 8; i++) {
dst >>>= 4;
int s = S(8 - i, (byte) (x & 0x3F)); // 00111111
s = s<<28;
dst = dst | s;
//dst |= s << 28;
x >>= 6;
}
// 4. permutation
return P(dst);
}
32
2.2.2 Code mã hóa
Hàm mã hóa xâu theo từng 8bytes mỗi lần, nếu không đủ 8bytes thì bù vào bằng 0
public static byte[] encryptCBC(byte[] message, byte[]
key,int phanbu) {
int i;
long cipherBlock;
byte[] ciphertext = new
byte[message.length+phanbu+8];
long k = getLongFromBytes(key, 0);
long previousCipherBlock = IV;
long length = message.length;
// Update previousCipherBlock
previousCipherBlock = cipherBlock;
}
cipherBlock = encryptBlock(length,k);
getBytesFromLongE(ciphertext,i,cipherBlock);
return ciphertext;
}
33
Hàm mã hóa xâu 8bytes với key 64bits
public static long encryptBlock(long m, long key) {
long[] subkeys = createSubkeys(key);
long ip = IP(m);
int l = (int) (ip >> 32);
int r = (int) (ip & 0xFFFFFFFFL);
long fp = FP(rl);
return fp;
}
34
// Decrypt the cipher block and XOR with
previousCipherBlock
// First previousCiphertext = Initial Vector
(IV)
long messageBlock = decryptBlock(cipherBlock,
k);
messageBlock = messageBlock ^
previousCipherBlock;
// Update previousCipherBlock
// previousCipherBlock = cipherBlock;
previousCipherBlock = cipherBlock;
}
return message;
}
// perform 16 rounds
// NOTE: reverse order of subkeys used!
35
for (int i = 15; i > -1; i--) {
int previous_l = l;
// the right half becomes the new left half.
l = r;
// the Feistel function is applied to the old
left half
// and the resulting value is stored in the
right half.
r = previous_l ^ feistel(r, subkeys[i]);
}
36
KẾT QUẢ VÀ ĐÁNH GIÁ
37
Giao diện khi nhập key sai
38
Giao diện nhận file mã hóa thành công
Có rất nhiều phương pháp mã hóa để đảm bảo an toàn dữ liệu. Để đánh giá
tính ưu việt một giải thuật mã hóa, người ta thường dựa vào các yếu tố: Tính bảo
mật, độ phức tạp, tốc độ thực hiện giải thuật và vấn đề phân khóa trong môi trường
nhiều người sử dụng.
Hiện nay phương pháp mã hóa DES được sử dụng rộng rãi nhất. Các chip
chuyên dung DES được thiết kế nhằm tăng tốc độ xử lí của DES. Rất nhiều nhà
toán học, tin học đã bỏ nhiều công nghiên cứu trong nhiều năm nhằm tìm cách phá
vỡ DES (tức là tìm ra cách giải mã trong khoảng thời gian ngắn hơn thời gian cần
để thử lần lượt tất cả các khóa). Ngoại trừ việc tìm ra 4 khóa yếu và 12 khóa tương
đối yếu cho tới nay chưa có một thông báo nào về việc tì ra cách phá vỡ phương
pháp mã hóa này. Để phá vỡ DES bằng phương pháp “ vét cạn” thử tất cả các khóa
trong không gian khóa cần có một khoản tiền lớn và đòi hỏi một khoảng thời gian
dài.
Nhược điểm của DES: nó là thuật toán mã hóa đối xứng. Khi phương pháp
này mới được tìm ra ý tưởng thực hiện 50000 tỷ phép mã hóa cần thiết để vượt mặt
DES bằng cách thử lần lượt các khóa có thể là điếu không thể làm được nhưng
ngày nay với sự phát triển mạnh của phần cứng liệu độ dài 56 bit đã đủ chưa? Và
39
các phép thay thế đã đủ phức tạp chưa? Để đạt được độ an toàn thông tin như
mong muốn, đó là vấn đề người ta vẫn đang bàn luận. Tuy vậy, DES đã được phân
tích kĩ lưỡng và công nhận là vững chắc. Các hạn chế của nó đã được hiểu rõ và có
thể xem xét trong quá trình thiết kế và để tăng độ an toàn hơn, ngày nay các hệ
thống mã hóa sử dụng DES mở rộng ( 3DES ), được ứng dụng rộng dãi. Với DES
mở rộng khóa có thể là 128 bit,…độ lớn khối có thể là 128 bit. Do vậy độ an toàn
mở rộng của DES cao hơn rất nhiều.
40
TÀI LIỆU THAM KHẢO
[2] https://viblo.asia/p/encryption-des-Qpmleq27lrd
[3] https://magenest.com/vi/ngon-ngu-lap-trinh-java/
41
PHỤ LỤC
Code Server
Main.java
package org.example;
import org.example.controller.ServerController;
…\src\main\java\org\example\service
DESService.java
package org.example.service;
42
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
/**Expansion Permutation, expand from 32 bit to 48 bit*/
private static final byte[] E = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
/** S-Box */
private static final byte[][] S = {{
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
}, {
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
}, {
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
}, {
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
}, {
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
}, {
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
43
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
}, {
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
}, {
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
}};
/**Permutation, result from The Feistel will use it to make Right
for next round */
private static final byte[] P = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
/** PC1 make key from 64bit to 56bit */
private static final byte[] PC1 = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
/**
* PC2 Permutation. The subkey generation process applies this
* permutation to transform its running 56-bit keystuff value
into
* the final set of 16 48-bit subkeys.
*/
private static final byte[] PC2 = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
44
};
/**cyclic shift rotate bit left for each of 16steps */
private static final byte[] rotations = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
private static long IP(long src) {
return permute(IP, 64, src);
} // 64-bit output
45
0x1E) >> 1));
int a = src &0x20; // 0010000
int b = (src & 0x01 ) <<4; // 000000001 >> 4 => 0001000
int c = ((src & 0x1E) >> 1); // 00001110 >>1 => 00000111
src = (byte)(a|b|c);
return S[boxNumber - 1][src];
}
46
private static int feistel(int r, /* 48 bits */ long subkey) {
// 1. expansion
long e = E(r);
// 2. key mixing
long x = e ^ subkey;
// 3. substitution
int dst = 0;
for (int i = 0; i < 8; i++) {
dst >>>= 4;
int s = S(8 - i, (byte) (x & 0x3F)); // 00111111
s = s<<28;
dst = dst | s;
//dst |= s << 28;
x >>= 6;
}
// 4. permutation
return P(dst);
}
/**
* Generate 16 48-bit subkeys based on the provided 64-bit key
* value.
*/
private static long[] createSubkeys(/* 64 bits */ long key) {
long subkeys[] = new long[16];
47
// perform the PC2 permutation
subkeys[i] = PC2(cd);
}
// Update previousCipherBlock
previousCipherBlock = cipherBlock;
}
cipherBlock = encryptBlock(length,k);
getBytesFromLongE(ciphertext,i,cipherBlock);
return ciphertext;
}
/**
* Encrypt a 64-bit block of plaintext message into a 64-bit
* ciphertext.
*/
48
long ip = IP(m);
// split the 32-bit value into 16-bit left and right halves.
int l = (int) (ip >> 32);
int r = (int) (ip & 0xFFFFFFFFL);
// perform 16 rounds
for (int i = 0; i < 16; i++) {
int previous_l = l;
// the right half becomes the new left half.
l = r;
// the Feistel function is applied to the old left half
// and the resulting value is stored in the right half.
r = previous_l ^ feistel(r, subkeys[i]);
}
int m = s.length();
for (int i = 0; i < s.length(); i += 2) {
//ba[i / 2] = (byte) (charToNibble(s.charAt(i)) << 4 |
charToNibble(s.charAt(i + 1)));
49
int c = charToNibble(s.charAt(i));
c= c << 4;
int d = charToNibble((s.charAt(i+1)));
ba[i / 2] = (byte) (c|d);
}
return ba;
}
return output.toString();
}
50
package org.example.service;
import org.example.model.Message;
import org.example.model.TextModel;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
os.close();
socket.close();
serverSocket.close();
}
}
Code Client
Main.java
package org.example;
import org.example.controller.ClientController;
51
public static void main(String[] args) {
ClientController controller = new ClientController();
controller.showClientView();
}
}
…\src\main\java\org\example\service
DESService.java
package org.example.service;
52
private static final byte[] E = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
/** S-Box */
private static final byte[][] S = {{
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
}, {
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
}, {
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
}, {
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
}, {
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
}, {
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
}, {
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
}, {
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
53
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
}};
/**Permutation, result from The Feistel will use it to make Right
for next round */
private static final byte[] P = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
/** PC1 make key from 64bit to 56bit */
private static final byte[] PC1 = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
/**
* PC2 Permutation. The subkey generation process applies this
* permutation to transform its running 56-bit keystuff value
into
* the final set of 16 48-bit subkeys.
*/
private static final byte[] PC2 = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
/**cyclic shift rotate bit left for each of 16steps */
private static final byte[] rotations = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
private static long IP(long src) {
return permute(IP, 64, src);
} // 64-bit output
54
return permute(FP, 64, src);
} // 64-bit output
55
private static long getLongFromBytes(byte[] ba, int offset) {
long l = 0;
for (int i = 0; i < 8; i++) {
byte value;
if ((offset + i) < ba.length) {
// and last bits determine which 16-value row to
// reference, so we transform the 6-bit input into an
// absolute
value = ba[offset + i];
} else {
value = 0;
}
l = l << 8 | (value & 0xFFL);
}
return l;
}
/** convert 64bit to 8bytes [array] */
private static void getBytesFromLongE(byte[] ba, int offset, long
l) {
for (int i = 7; i > -1; i--) {
if ((offset + i) < ba.length) {
ba[offset + i] = (byte) (l & 0xFF);
l = l >> 8;
} else {
continue;
}
}
}
private static void getBytesFromLongD(byte[] ba, int offset, long
l) {
for (int i = 7; i > -1; i--) {
if ((offset + i) < ba.length) {
ba[offset + i] = (byte) (l & 0xFF);
l = l >> 8;
} else {
l = l >> 8;
continue;
}
}
}
/**
* The Feistel function is the heart of DES.
*/
private static int feistel(int r, /* 48 bits */ long subkey) {
// 1. expansion
long e = E(r);
// 2. key mixing
long x = e ^ subkey;
// 3. substitution
int dst = 0;
56
for (int i = 0; i < 8; i++) {
dst >>>= 4;
int s = S(8 - i, (byte) (x & 0x3F)); // 00111111
s = s<<28;
dst = dst | s;
//dst |= s << 28;
x >>= 6;
}
// 4. permutation
return P(dst);
}
/**
* Generate 16 48-bit subkeys based on the provided 64-bit key
* value.
*/
private static long[] createSubkeys(/* 64 bits */ long key) {
long subkeys[] = new long[16];
57
private static int charToNibble(char c) {
if (c >= '0' && c <= '9') {
return (c - '0');
} else if (c >= 'a' && c <= 'f') {
return (10 + c - 'a');
} else if (c >= 'A' && c <= 'F') {
return (10 + c - 'A');
} else {
return 0;
}
}
int m =s.length();
for (int i = 0; i < s.length(); i += 2) {
//ba[i / 2] = (byte) (charToNibble(s.charAt(i)) << 4 |
charToNibble(s.charAt(i + 1)));
int c = charToNibble(s.charAt(i));
c= c << 4;
int d = charToNibble((s.charAt(i+1)));
ba[i / 2] = (byte) (c|d);
}
return ba;
}
58
// generate the 16 subkeys
long[] subkeys = createSubkeys(key);
// split the 32-bit value into 16-bit left and right halves.
int l = (int) (ip >> 32);
int r = (int) (ip & 0xFFFFFFFFL);
// perform 16 rounds
// NOTE: reverse order of subkeys used!
for (int i = 15; i > -1; i--) {
int previous_l = l;
// the right half becomes the new left half.
l = r;
// the Feistel function is applied to the old left half
// and the resulting value is stored in the right half.
r = previous_l ^ feistel(r, subkeys[i]);
}
59
// Store the messageBlock in the correct position in
message
getBytesFromLongD(message, i, messageBlock);
// Update previousCipherBlock
// previousCipherBlock = cipherBlock;
previousCipherBlock = cipherBlock;
}
return message;
}
/** convert from Hex to String */
private static String hexToAscii(String hexStr) {
hexStr = hexStr.replace(" ", "");
StringBuilder output = new StringBuilder("");
return output.toString();
}
import org.example.model.Message;
import org.example.model.TextModel;
import java.io.*;
import java.net.Socket;
60
private final Integer SOCKET_PORT = 9098;
private final String SERVER = "127.0.0.1";
private final String FILE_TO_RECEIVED =
"C:/Users/Thieu/Downloads/DecryptedText.txt";
InputStream is = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
Message receiveObject = (Message) ois.readObject();
FileOutputStream fos = new
FileOutputStream(FILE_TO_RECEIVED);
BufferedOutputStream bos = new BufferedOutputStream(fos);
String decryptedText =
DESService.decryptText(receiveObject.getEncryptedText(),
receiveObject.getKey());
bos.write(decryptedText.getBytes());
bos.flush();
fos.close();
is.close();
socket.close();
61