Thám mã là “nghệ thuật” tìm lại bản thông điệp gốc bằng cách phân tích bản mã.
Mục đớch chớnh của mật mó là phải giữ bớ mật bản rừ (hoặc khoỏ, hoặc cả
hai) khỏi những ngời nghe trộm (attacker). Thám mã là cần phục hồi bản rõ của một thông điệp từ bản mã mà không có khoá. Nếu thành công, ngời phân tích mã
cú thể thu đợc bản rừ hoặc khoỏ, hoặc cũng cú thể tỡm thấy điểm yếu trong một hệ thống mã hoá. Các thuật toán sử dụng cho phần lớn các hệ thống mã hoá là nổi tiếng, vì vậy chúng ta giả thiết rằng ngời thám mã đã biết thuật toán để bắt đầu thám mã.
Nh vậy, vấn đề cốt yếu của một hệ mó hoỏ tốt là việc khụi phục bản rừ P từ bản mã C khi biết Dk phải là khó, hoặc tốt hơn là không thể đợc.
Có 6 tình huống mà ngời thám mã có thể có khi phân tích. Trong các tình huống đó giả sử rằng ngời thám mã đã biết thuật toán đợc dùng để mã hoá:
1.Chỉ biết bản mã (Ciphertext-only attack).
Trong trờng hợp này, ngời thám mã có bản mã của một thông điệp, và biết đợc thuật toỏn đợc dựng để mó hoỏ. Cụng việc của ngời thỏm mó là phải tỡm đợc bản rừ của thông điệp, và tốt hơn hết là tìm ra khoá đợc sử dụng để mã hoá thông điệp, để từ đó giải mã những thông điệp khác đợc mã hoá với cùng khoá đó.
Để việc phân tích của ngời thám mã có hiệu quả thì tốt hơn hết là bản mã phải dài.
Trong những hệ đơn giản, ví dụ nh CAESAR, một bản mã ngắn cũng đa lại kết quả
bởi vì chỉ có duy nhất một khoá đợc sử dụng để mã hoá. Trong những hệ hoàn chỉnh hơn thì bản mã dài là cần thiết. Hiệu quả của phơng pháp phân tích có thể dựa trờn thụng tin thống kờ liờn quan tới ngụn ngữ mà bản rừ đợc sử dụng. Vớ dụ nh thông tin về tần số xuất hiện của mỗi ký tự riêng lẻ trong tiếng Anh.
Đầu vào: C1=Ek(P1), C2=Ek(P2),... Ci=Ek(Pi)
Cần tìm: hoặc P1, P 2,... Pi; k; hoặc một thuật toán để nhận đợc Pi+1 từ Ci+1=Pk(Pi+1)
2.Biết bản rõ (Known-plaintext attack).
Ngời thám mã không chỉ biết bản mã của một vài thông điệp mà còn biết cả
bản rõ của những thông điệp này. Công việc của ngời thám mã là tìm ra khoá (hoặc các khoá) đợc sử dụng để mã hoá các thông điệp hoặc thuật toán để giải mã bất kỳ một thông điệp mới nào đợc mã hoá bằng khoá đó.
Đầu vào: P1, C1=Ek(P1), P2, C2=Ek(P2),... Pi, Ci=Ek(Pi)
Cần tìm: hoặc k, hoặc một thuật toán để nhận đợc Pi+1 từ Ek(Pi+1) 3. Lựa chọn bản rõ (Chosen-plaintext attack).
Ngời thỏm mó khụng chỉ phõn tớch bản mó mà cũn đợc kết hợp với bản rừ của một vài thông điệp, nhng các bản rõ không là tuỳ ý mà do ngời thám mã phải lựa chọn. Trờng hợp này tốt hơn trờng hợp (2) đối với ngời thám mã, bởi vì ngời thỏm mó cú thể chọn khối bản rừ đặc trng để giải mó, nú cú thể mang lại nhiều thông tin về khoá. Công việc của ngời thám mã là tìm khoá (hoặc các khoá) đợc sử dụng để mã hoá các thông điệp hoặc một thuật toán để giải mã bất cứ thông điệp đã
đợc mã hoá mới nào bằng các khoá đó.
Đầu vào: P1, C1=Ek(P1), P2, C2=Ek(P2),... Pi, Ci=Ek(Pi), ngời thám mã đợc chọn P1, P2,... Pi
Cần tìm: hoặc k, hoặc một thuật toán để nhận đợc Pi+1 từ Ci+1=Ek(Pi+1) 4. Lựa chọn bản rõ thích hợp (Adaptive-chose-plaintext attack).
Đõy là một trờng hợp đặc biệt của trờng hợp bản rừ đợc lựa chọn. Ngời thỏm mó
khụng chỉ cú thể đợc lựa chọn bản rừ mà nú đó đợc mó hoỏ, mà họ cũn cú thể biến
đổi những điểm cần thiết dựa trên kết quả của những lần mã hoá trớc. Với trờng hợp bản rừ đợc lựa chọn, ngời thỏm mó cú thể lựa chọn một khối bản rừ lớn để giải mó; trong trờng hợp bản rừ đợc lựa chọn thớch hợp họ cú thể lựa chọn một khối bản rừ nhỏ hơn sau đú lựa chọn khối khỏc dựa vào kết quả của khối đầu tiờn, v.v...
5. Lựa chọn bản mã (Chosen-plaintext attack).
Ngời thỏm mó cú thể chọn trong cỏc bản mó khỏc nhau và biết đợc bản rừ.
Công việc của ngời thám mã là tìm khoá.
Đầu vào: C1, P1=Dk(C1), C2, P2=Dk(C2),... Ci, Pi=Dk(Ci) Cần tìm: k
6. Lựa chọn khoá (Chosen-Key).
Ngời thám mã biết phơng pháp mã hoá Ek và cố tìm phơng pháp giải mã tơng ứng Dk trớc khi nhận bất cứ mẫu bản mã nào. Trong trờng hợp này ngời thám mã
có rất nhiều thời gian để làm việc.
Trờng hợp (5), (6) thờng đợc ứng dụng chủ yếu đối với các hệ thống mã hoá sử dụng khoá công khai.
Một điểm đáng chú ý khác là đa số các kỹ thuật thám mã đều dùng phơng pháp thống kê tần suất xuất hiện của các từ, các ký tự trong bản mã. Sau đó thực hiện việc thử thay thế với các chữ cái có tần suất xuất hiện tơng đồng trong ngôn ngữ tự nhiên. Tại đây chúng ta chỉ xem xét đối với ngôn ngữ thông dụng nhất hiện nay đó là tiếng Anh. Việc thống kê tần suất xuất hiện của các ký tự trong trờng hợp này đ- ợc tiến hành dựa trên các bài báo, sách, tạp chí và các văn bản cùng với một số loại khác ...
Sau đây là bảng thống kê tần suất xuất hiện của 26 chữ cái trong bảng chữ cái tiếng Anh theo tài liệu của Beker và Piper.
Ký tự Xác Suất Ký tự Xác suất Ký tự Xác suất
A 0.082 J 0.002 S 0.063
B 0.015 K 0.008 T 0.091
C 0.028 L 0.040 U 0.028
D 0.043 M 0.024 V 0.010
E 0.127 N 0.067 W 0.023
F 0.022 O 0.075 X 0.001
G 0.020 P 0.019 Y 0.020
I 0.070 R 0.060
Cùng với việc thống kê các tần xuất của các ký tự trong tiếng Anh, việc thống kê tần suất xuất hiện thờng xuyên của các dãy gồm 2 hoặc 3 ký tự liên tiếp nhau cũng có một vai trò quan trọng trong công việc thám mã. Sysu Deck đa ra 30 bộ đôi xuất hiện thờng xuyên của tiếng Anh đợc sắp theo thứ tự giảm dần nh sau :
Tính hữu dụng của các phép thống kê ký tự và các dãy ký tự đợc ngời phân tích mã
khai thác triệt để trong những lần thám mã. Khi thực hiện việc thám mã ngời phân tích thống kê các ký tự trong bản mã, từ đó so sánh với bản thống kê mẫu và đa ra các ký tự phỏng đoán tơng tự. Phơng pháp này đợc sử dụng thờng xuyên và đem lại hiệu quả khá cao.
Cặp chữ Tần suất Cặp chữ Tần suất Cặp chữ Tần suất
TH 10.00 ED 4.12 OF 3.38
HE 9.50 TE 4.04 IT 3.26
IN 7.17 TI 4.00 AL 3.15
ER 6.65 OR 3.98 AS 3.00
RE 5.92 ST 3.81 HA 3.00
ON 5.70 AR 3.54 NG 2.92
AN 5.63 ND 3.52 CO 2.80
EN 4.76 TO 3.50 SE 2.75
AT 4.72 NT 3.44 ME 2.65
ES 4.24 IS 3.43 DE 2.65
Phần iii: cài đặt một số thuật toán
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
public class mahoa extends JFrame implements ActionListener {
Public String[]a = new String[]{"a","b","c","d","e","f","g","h","i","j","k","l","m"
,"n","o","p","q","s","r","t","u","v","x","y","z","w"};
public String[]code=new String[62];
public String xauma=new String();
public String banma=new String();
JTextArea t1=new JTextArea(5,5);
JLabel l1=new JLabel("chua ma");
JButton[] b=new JButton[]{new JButton("ma vong"),new JButton("ma hemiaffine"),new JButton("ma tt"),new JButton("ma vigenere"),new JButton("ma ts")};
JButton[] g=new JButton[]{new JButton("gma vong"),new JButton("gma hemiaffin"),new JButton("gma tt"),new JButton("gma vigenere"),new JButton("gma ts")};
public mahoa() {
setLayout(new FlowLayout());
add(t1);
add(l1);
for(int i=0;i<b.length;i++) {
b[i].addActionListener(this);
add(b[i]);
g[i].addActionListener(this);
add(g[i]);
}
}
public String mavong(int k) {
String xauma=t1.getText();
System.out.println("xau ma la: "+xauma);
int l=xauma.length();
String t;
String kq = "";
System.out.println("5%2"+5%2);
for(int i=0;i<l;i++) {
t=xauma.substring(i,i+1);
for(int j=0;j<26;j++) {
if(t.compareTo(a[j])==0) {
kq=kq+a[j+k];
} } }
System.out.println("xau ma la: "+kq);
l1.setText("Xau ma la: "+kq);
banma=kq;
return kq;
}
public String hemiaffin(int a1,int b1) {
String xauma=t1.getText();
System.out.println("xau ma la: "+xauma);
int l=xauma.length();
String t;
String kq ="";
for(int i=0;i<l;i++) {
t=xauma.substring(i,i+1);
for(int j1=0;j1<26;j1++) {
if(t.compareTo(a[j1])==0) {
int j=(a1*j1+b1)%26;
kq=kq+a[j];
} }
}
//System.out.println("xau ma la: "+kq);
l1.setText("Xau ma la: "+kq);
banma=kq;
return kq;
}
public String ghemiaffin(int a1,int b1) {
String xauma=banma;
System.out.println("xau ma la: "+xauma);
int l=xauma.length();
String t;
String kq ="";
for(int i=0;i<l;i++) {
t=xauma.substring(i,i+1);
for(int j1=0;j1<26;j1++)
{
if(t.compareTo(a[j1])==0) {
int j = 0;
System.out.println(j1);
int c=tinhx(a1,b1,j1);
if(c!=-1) {
j=c;
}
System.out.println(j);
kq=kq+a[j];
} }
}
System.out.println("xau ma la: "+kq);
l1.setText("Xau ma la: "+kq);
return kq;
}
public int tinhx(int a, int b,int j) {
int x=-1;
int m=(25*a-j+b)/26;
for(x=0;x<26;x++)
for(int k=0;k<=25;k++) {
if((a*x-26*k==(j-b))) {
System.out.println("x tim duoc la:"+x);
return x;
} }
return x;
}
public String thaythe(int n,int[] r) {
String xauma=t1.getText();
System.out.println("xau ma la: "+xauma);
int l=xauma.length();
String kq ="";
int d=0;
while(l>d) {
int j=r[d%n]+((int) Math.floor((double) d/n))*n;
System.out.println(j);
kq=kq+xauma.substring(j,j+1);
d++;
}
l1.setText("Xau ma la: "+kq);
banma=kq;
return kq;
}
public String gthaythe(int n,int[] r) {
String xauma=banma;
System.out.println("xau ma la: "+xauma);
int l=xauma.length();
String[] tg=new String[l];
String kq ="";
int d=0;
while(l>d) {
int j=r[d%n]+((int) Math.floor((double) d/n))*n;
System.out.println(j);
tg[j]=xauma.substring(d,d+1);
d++;
}
for(int j=0;j<tg.length;j++) {
kq=kq+tg[j];
}
l1.setText("Xau ma la: "+kq);
banma=kq;
return kq;
}
public String vigenere(String k) {
String xauma=t1.getText();
int lx=xauma.length();
int l=k.length();
int r[]=new int[l];
int m = 0;
String kq ="";
for(int i=0;i<l;i++) {
String t=k.substring(i,i+1);
for(int j=0;j<26;j++) if(t.compareTo(a[j])==0) {
r[i]=j;
} }
for(int i=0;i<lx;i++) {
String t=xauma.substring(i,i+1);
for(int j=0;j<26;j++) if(t.compareTo(a[j])==0) {
m=j;
}
int ma=(m+r[i%l])%26;
kq=kq+a[ma];
}
l1.setText("Xau ma la: "+kq);
banma=kq;
return kq;
}
public String gvigenere(String k) {
String xauma=banma;
int lx=xauma.length();
int l=k.length();
int r[]=new int[l];
String kq ="";
for(int i=0;i<l;i++) {
String t=k.substring(i,i+1);
for(int j=0;j<26;j++) if(t.compareTo(a[j])==0) {
r[i]=j;
} }
int m = 0;
for(int i=0;i<lx;i++) {
String t=xauma.substring(i,i+1);
for(int j=0;j<26;j++) if(t.compareTo(a[j])==0) {
m=j;
System.out.println("ma cua kt la:"+m);
}
int ma=(m-r[i%l])%26;
kq=kq+a[ma];
}
l1.setText("Xau ma la: "+kq);
return kq;
}
public String tusinh(int k) {
String xauma=t1.getText();
int l=xauma.length();
String kq="";
int[] m = new int[l];
for(int i=0;i<l;i++) {
String t=xauma.substring(i,i+1);
for(int j=0;j<26;j++) if(t.compareTo(a[j])==0) {
m[i]=j;
}
int ma = 0;
if(i>0) k=m[i-1];
ma=(m[i]+k)%26;
m[i]=ma;
kq=kq+a[ma];
}
l1.setText("Xau ma la: "+kq);
banma=kq;
return kq;
}
public String gtusinh(int k) {
String xauma=banma;
int l=xauma.length();
String kq="";
int ma = 0;
int[] m = new int[l];
for(int i=0;i<l;i++) {
String t=xauma.substring(i,i+1);
for(int j=0;j<26;j++) if(t.compareTo(a[j])==0)
{
m[i]=j;
}
if(i>0)k=m[i-1];
ma=(m[i]-k)%26;
if (ma<0)ma=ma+26;
System.out.println("ma ky tu la:" +ma);
kq=kq+a[ma];
}
l1.setText("Xau ma la: "+kq);
return kq;
}
public String gmavong(int k) {
String xauma=banma;
System.out.println("xau ma la: "+xauma);
int l=xauma.length();
String t;
String kq = "";
for(int i=0;i<l;i++) {
t=xauma.substring(i,i+1);
for(int j=0;j<26;j++) {
if(t.compareTo(a[j])==0) {
kq=kq+a[(j-k)%26];
} }
}
System.out.println("xau ma la: "+kq);
l1.setText("Xau ma la: "+kq);
return kq;
}
public static void main() {
mahoa m=new mahoa();
m.setSize(100,100);
m.setVisible(true);
}
public Object getValue(String key) {
return null;
}
public void putValue(String key, Object value) {
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==b[0]) {
mavong(4);
//hemiaffin(4,5);
//vigenere("trandong");
//gvigenere("trandong");
// gtusinh(4);
//int[] r={0,3,1,2};
//gthaythe(4,r);
}
if(e.getSource()==b[1]) {
hemiaffin(4,5);
}
if(e.getSource()==b[2]) {
int[] r={0,3,1,2};
thaythe(4,r);
}
if(e.getSource()==b[3]) {
vigenere("trandong");
}
if(e.getSource()==b[4]) {
tusinh(4);
}
if(e.getSource()==g[0]) {
gmavong(4);
}
if(e.getSource()==g[1]) {
ghemiaffin(4,5);
}
if(e.getSource()==g[2]) {
int[] r={0,3,1,2};
gthaythe(4,r);