对称密码体制

对称密码体制
对称密码体制

云南大学数学与统计学实验教学中心实验报告

一、实验目的:

通过实验掌握AES加密实验的构造算法,以及其重要思想。

二、实验内容:

查阅资料,实现AES密码体制的编码算法、译码算法、子密钥生成算法

三、实验环境

Win7、Eclipse

四、实验过程(请学生认真填写):

实验过程、结果以及相应的解释:

1. 预备知识

密码学中的高级加密标准(Advanced Encryption Standard,AES),是一种对称加密的方法。

本实验使用Java平台来编写的,虽然在java中已经很好的实现了AES等安全机制,但是为了了解如何实现,还是写了一个AES加密的java程序。

2. 实验过程

A、原理分析:

大多数AES计算是在一个特别的有限域完成的。

AES加密过程是在一个4×4的字节矩阵上运作,这个矩阵又称为“体(state)”,其初值就

是一个明文区块(矩阵中一个元素大小就是明文区块中的一个Byte)。(Rijndael加密法因支

持更大的区块,其矩阵行数可视情况增加)加密时,各轮AES加密循环(除最后一轮外)均

包含4个步骤:

AddRoundKey —矩阵中的每一个字节都与该次回合金钥(round key)做XOR运算;每个子

密钥由密钥生成方案产生。

SubBytes —通过一个非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。

ShiftRows —将矩阵中的每个横列进行循环式移位。

MixColumns —为了充分混合矩阵中各个直行的操作。这个步骤使用线性转换来混合每列的

四个字节。

最后一个加密循环中省略MixColumns步骤,而以另一个AddRoundKey取代。

B、具体代码如下:

//如6.2,若是将每一行看做是一个对象的话

//具体实现的整体结构思想如此下图

结果如下:

//得到结果与真实结果一样。说明正确

具体代码如下:

由于所写代码过多,所以,本代码附在最后!

五、实验总结

1.遇到的问题及分析:

遇到问题:其实这次编写程序遇到的问题还是蛮多的!例如S盒子的生成、逆S盒子的生成,算法中的每一步轮转,密钥生成,密钥长度等都遇到了问题。由于时间仓促,这里就不一一举出来了。

分析并解决:-通过图书馆查询相应资料以及课本查阅得到了一些解决。同时在网上查找到了一使用C++编写的程序代码以及算法理论。得到了解决。

2.体会和收获。

编程实现了AES,个人感觉AEs实现起来还是比较困难的(对于我来说)因为他中间的矩阵操作复杂。当然收获就是能有一定能力来编写这样的一个程序了。

六、参考文献

计算机网络课本。

七、教师评语:

附录:

AES代码

*************************Aes.java***************************** package AES;

/**

* AES字节数组加密算法类

*/

public class Aes {

private int Nb;// 以32位为单位的字长

private int Nk;// 以32位为单位的密钥长度

private int Nr;// 轮数

private byte[] key;// 密钥

private byte[][] Sbox;// S盒矩阵

private byte[][] iSbox;// s盒逆矩阵

private byte[][] w;// 密钥调度表

private byte[][] Rcon;// 轮常数表

private byte[][] State;// 状态矩阵

/**

* 构造方法

* @param keySize

* @param keyBytes

*/

public Aes(int keySize, byte[] keyBytes, int Nb) { SetNbNkNr(keySize, Nb);

this.key = new byte[this.Nk * 4];

this.key = keyBytes;

BuildSbox();

BuildInvSbox();

BuildRcon();

KeyExpansion();

}

/**

* 生成Rcon轮常数矩阵

*/

private void BuildRcon() {

this.Rcon = new byte[100][4];

Rcon[0][0] = 0x00;// Rcon[1][0]=0x01;

for (int i = 1; i < 100; i++) {

Rcon[i][0] = gfmultby02(Rcon[i - 1][0]);

}

}

/**

* 设置Nb,Nk,Nr

* @param keysize

*/

private void SetNbNkNr(int keysize, int Nb) { this.Nb = Nb;

switch (keysize) {

case KEYSIZE.Bit128:

this.Nk = 4;

this.Nr = 10;

break;

case KEYSIZE.Bit192:

this.Nk = 6;

this.Nr = 12;

break;

case KEYSIZE.Bit256:

this.Nk = 8;

this.Nr = 14;

break;

}

}

/**

* 生成S盒矩阵

*/

private void BuildSbox() {

this.Sbox = new byte[][] {

/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */

/* 0 */{ 0x63, 0x7c, 0x77, 0x7b, (byte) 0xf2, 0x6b, 0x6f,

(byte) 0xc5, 0x30, 0x01, 0x67, 0x2b, (byte) 0xfe,

(byte) 0xd7, (byte) 0xab, 0x76 },

/* 1 */{ (byte) 0xca, (byte) 0x82, (byte) 0xc9, 0x7d,

(byte) 0xfa, 0x59, 0x47, (byte) 0xf0, (byte) 0xad,

(byte) 0xd4, (byte) 0xa2, (byte) 0xaf, (byte) 0x9c,

(byte) 0xa4, 0x72, (byte) 0xc0 },

/* 2 */{ (byte) 0xb7, (byte) 0xfd, (byte) 0x93, 0x26, 0x36,

0x3f, (byte) 0xf7, (byte) 0xcc, 0x34, (byte) 0xa5,

(byte) 0xe5, (byte) 0xf1, 0x71, (byte) 0xd8, 0x31, 0x15 }, /* 3 */{ 0x04, (byte) 0xc7, 0x23, (byte) 0xc3, 0x18,

(byte) 0x96, 0x05, (byte) 0x9a, 0x07, 0x12,

(byte) 0x80, (byte) 0xe2, (byte) 0xeb, 0x27,

(byte) 0xb2, 0x75 },

/* 4 */{ 0x09, (byte) 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a,

(byte) 0xa0, 0x52, 0x3b, (byte) 0xd6, (byte) 0xb3,

0x29, (byte) 0xe3, 0x2f, (byte) 0x84 },

/* 5 */{ 0x53, (byte) 0xd1, 0x00, (byte) 0xed, 0x20,

(byte) 0xfc, (byte) 0xb1, 0x5b, 0x6a, (byte) 0xcb,

(byte) 0xbe, 0x39, 0x4a, 0x4c, 0x58, (byte) 0xcf }, /* 6 */{ (byte) 0xd0, (byte) 0xef, (byte) 0xaa, (byte) 0xfb,

0x43, 0x4d, 0x33, (byte) 0x85, 0x45, (byte) 0xf9, 0x02,

0x7f, 0x50, 0x3c, (byte) 0x9f, (byte) 0xa8 },

/* 7 */{ 0x51, (byte) 0xa3, 0x40, (byte) 0x8f, (byte) 0x92,

(byte) 0x9d, 0x38, (byte) 0xf5, (byte) 0xbc,

(byte) 0xb6, (byte) 0xda, 0x21, 0x10, (byte) 0xff,

(byte) 0xf3, (byte) 0xd2 },

/* 8 */{ (byte) 0xcd, 0x0c, 0x13, (byte) 0xec, 0x5f,

(byte) 0x97, 0x44, 0x17, (byte) 0xc4, (byte) 0xa7,

0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 },

/* 9 */{ 0x60, (byte) 0x81, 0x4f, (byte) 0xdc, 0x22, 0x2a,

(byte) 0x90, (byte) 0x88, 0x46, (byte) 0xee,

(byte) 0xb8, 0x14, (byte) 0xde, 0x5e, 0x0b, (byte) 0xdb }, /* a */{ (byte) 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,

(byte) 0xc2, (byte) 0xd3, (byte) 0xac, 0x62,

(byte) 0x91, (byte) 0x95, (byte) 0xe4, 0x79 },

/* b */{ (byte) 0xe7, (byte) 0xc8, 0x37, 0x6d, (byte) 0x8d,

(byte) 0xd5, 0x4e, (byte) 0xa9, 0x6c, 0x56,

(byte) 0xf4, (byte) 0xea, 0x65, 0x7a, (byte) 0xae, 0x08 }, /* c */{ (byte) 0xba, 0x78, 0x25, 0x2e, 0x1c, (byte) 0xa6,

(byte) 0xb4, (byte) 0xc6, (byte) 0xe8, (byte) 0xdd,

0x74, 0x1f, 0x4b, (byte) 0xbd, (byte) 0x8b, (byte) 0x8a }, /* d */{ 0x70, 0x3e, (byte) 0xb5, 0x66, 0x48, 0x03,

(byte) 0xf6, 0x0e, 0x61, 0x35, 0x57, (byte) 0xb9,

(byte) 0x86, (byte) 0xc1, 0x1d, (byte) 0x9e },

/* e */{ (byte) 0xe1, (byte) 0xf8, (byte) 0x98, 0x11, 0x69,

(byte) 0xd9, (byte) 0x8e, (byte) 0x94, (byte) 0x9b,

0x1e, (byte) 0x87, (byte) 0xe9, (byte) 0xce, 0x55,

0x28, (byte) 0xdf },

/* f */{ (byte) 0x8c, (byte) 0xa1, (byte) 0x89, 0x0d,

(byte) 0xbf, (byte) 0xe6, 0x42, 0x68, 0x41,

(byte) 0x99, 0x2d, 0x0f, (byte) 0xb0, 0x54,

(byte) 0xbb, 0x16 } };

}

/**

* 生成逆s盒矩阵

*/

private void BuildInvSbox() {

int x, y;

this.iSbox = new byte[16][16];

for (int i = 0; i < 16; i++) {

for (int j = 0; j < 16; j++) {

x = (int) ((this.Sbox[i][j] >> 4) & 0x0f);

y = (int) (this.Sbox[i][j] & 0x0f);

this.iSbox[x][y] = (byte) (16 * i + j);

}

}

}

/**

* 扩展密钥

*/

private void KeyExpansion() {

this.w = new byte[Nb * (Nr + 1)][4];

for (int row = 0; row < Nk; ++row) {

this.w[row][0] = this.key[4 * row];

this.w[row][1] = this.key[4 * row + 1];

this.w[row][2] = this.key[4 * row + 2];

this.w[row][3] = this.key[4 * row + 3];

}

byte[] temp = new byte[Nb];

for (int row = Nk; row < Nb * (Nr + 1); ++row) {

temp[0] = this.w[row - 1][0];

temp[1] = this.w[row - 1][1];

temp[2] = this.w[row - 1][2];

temp[3] = this.w[row - 1][3];

if (row % Nk == 0) {

temp = SubWord(RotWord(temp));

temp[0] = (byte) (temp[0] ^ this.Rcon[row / Nk][0]);

temp[1] = (byte) (temp[1] ^ this.Rcon[row / Nk][1]);

temp[2] = (byte) (temp[2] ^ this.Rcon[row / Nk][2]);

temp[3] = (byte) (temp[3] ^ this.Rcon[row / Nk][3]);

} else if (Nk > 6 && (row % Nk == 4)) {

temp = SubWord(temp);

}

this.w[row][0] = (byte) (this.w[row - Nk][0] ^ temp[0]);

this.w[row][1] = (byte) (this.w[row - Nk][1] ^ temp[1]);

this.w[row][2] = (byte) (this.w[row - Nk][2] ^ temp[2]);

this.w[row][3] = (byte) (this.w[row - Nk][3] ^ temp[3]);

}

}

/**

* SubWord方法

* @param subWord

* @return

*/

private byte[] SubWord(byte[] subWord) {

for (int c = 0; c < subWord.length; ++c) {

subWord[c] = this.Sbox[(subWord[c] >> 4) & 0x0f][(subWord[c] & 0x0f)];

}

return subWord;

}

/**

* RotWord方法

* @param rotWord

* @return

*/

private byte[] RotWord(byte[] rotWord) {

byte[] temp = rotWord;

byte[] b = new byte[4];

for (int i = 0; i < 4; i++) {

b[i] = temp[(i + 1) % 4];

}

return b;

}

/**

* 轮密钥加

* @param round

*/

private void AddRoundKey(int round) {

for (int r = 0; r < 4; ++r) {

for (int c = 0; c < Nb; ++c) {

this.State[r][c] = (byte) (this.State[r][c] ^ w[(round * Nb)

+ c][r]);

}

}

}

/**

* SubBytes方法

*/

private void SubBytes() {

for (int r = 0; r < 4; ++r) {

for (int c = 0; c < Nb; ++c) {

this.State[r][c] = this.Sbox[(this.State[r][c] >> 4) &

0x0f][(this.State[r][c] & 0x0f)];

}

}

}

/**

* InvSubBytes方法

*/

private void InvSubBytes() {

for (int r = 0; r < 4; ++r) {

for (int c = 0; c < Nb; ++c) {

this.State[r][c] = this.iSbox[(this.State[r][c] >> 4) &

0x0f][(this.State[r][c] & 0x0f)];

}

}

}

/**

* 行移位

*/

private void ShiftRows() {

byte[][] temp = new byte[4][Nb];

for (int r = 0; r < 4; ++r) {

for (int c = 0; c < Nb; ++c) {

temp[r][c] = this.State[r][c];

}

}

for (int r = 1; r < 4; ++r) {

for (int c = 0; c < Nb; ++c) {

this.State[r][c] = temp[r][(c + r) % Nb];

}

}

}

/**

* 逆行移位

*/

private void InvShiftRows() {

byte[][] temp = new byte[4][Nb];

for (int r = 0; r < 4; ++r) {

for (int c = 0; c < Nb; ++c) {

temp[r][c] = this.State[r][c];

}

}

for (int r = 1; r < 4; ++r) {

for (int c = 0; c < Nb; ++c) {

this.State[r][c] = temp[r][(c - r + Nb) % Nb];

}

}

}

/**

* 列混合

*/

private void MixColumns() {

byte[][] temp = new byte[4][Nb];

for (int r = 0; r < 4; ++r) {

for (int c = 0; c < Nb; ++c) {

temp[r][c] = this.State[r][c];

}

}

for (int c = 0; c < Nb; ++c) {

this.State[0][c] = (byte) (gfmultby02(temp[0][c])

^ gfmultby03(temp[1][c]) ^ gfmultby01(temp[2][c]) ^

gfmultby01(temp[3][c]));

this.State[1][c] = (byte) (gfmultby01(temp[0][c])

^ gfmultby02(temp[1][c]) ^ gfmultby03(temp[2][c]) ^

gfmultby01(temp[3][c]));

this.State[2][c] = (byte) (gfmultby01(temp[0][c]) ^ (gfmultby01(temp[1][c]) ^ gfmultby02(temp[2][c]) ^ gfmultby03(temp[3][c])));

this.State[3][c] = (byte) (gfmultby03(temp[0][c])

^ gfmultby01(temp[1][c]) ^ (gfmultby01(temp[2][c]) ^

gfmultby02(temp[3][c])));

}

}

/**

* 逆列混合

*/

private void InvMixColumns() {

byte[][] temp = new byte[4][Nb];

for (int r = 0; r < 4; ++r) {

for (int c = 0; c < Nb; ++c) {

temp[r][c] = this.State[r][c];

}

}

for (int c = 0; c < Nb; c++) {

this.State[0][c] = (byte) (gfmultby0e(temp[0][c])

^ gfmultby0b(temp[1][c]) ^ gfmultby0d(temp[2][c]) ^

gfmultby09(temp[3][c]));

this.State[1][c] = (byte) (gfmultby09(temp[0][c])

^ gfmultby0e(temp[1][c]) ^ gfmultby0b(temp[2][c]) ^

gfmultby0d(temp[3][c]));

this.State[2][c] = (byte) (gfmultby0d(temp[0][c]) ^ (gfmultby09(temp[1][c]) ^ gfmultby0e(temp[2][c]) ^ gfmultby0b(temp[3][c])));

this.State[3][c] = (byte) (gfmultby0b(temp[0][c])

^ gfmultby0d(temp[1][c]) ^ (gfmultby09(temp[2][c]) ^

gfmultby0e(temp[3][c])));

}

}

// 有限域GF(28)部分变换

private byte gfmultby01(byte b) {

return b;

}

private byte gfmultby02(byte b) {

if (((b >> 7) & 0x01) == 0) // !!!!!!!这里比较大小的时候注意符号位

return (byte) (b << 1);

else

return (byte) ((b << 1) ^ (byte) 0x1b);

}

private byte gfmultby03(byte b) {

return (byte) (gfmultby02(b) ^ gfmultby01(b));

}

private byte gfmultby09(byte b) {

return (byte) (gfmultby02(gfmultby02(gfmultby02(b))) ^ gfmultby01(b));

}

private byte gfmultby0b(byte b) {

return (byte) (gfmultby02(gfmultby02(gfmultby02(b))) ^ gfmultby02(b) ^

gfmultby01(b));

}

private byte gfmultby0d(byte b) {

return (byte) (gfmultby02(gfmultby02(gfmultby02(b)))

^ gfmultby02(gfmultby02(b)) ^ gfmultby01(b));

}

private byte gfmultby0e(byte b) {

return (byte) (gfmultby02(gfmultby02(gfmultby02(b)))

^ gfmultby02(gfmultby02(b)) ^ gfmultby02(b));

}

/**

* 加密过程

* @param input

* @param output

*/

public void Cipher(byte[] input, byte[] output) {

this.State = new byte[4][Nb];

for (int i = 0; i < (4 * Nb); i++) {

this.State[i / Nb][i % Nb] = input[i];

}// 初始化状态矩阵

AddRoundKey(0);// 轮密钥加

for (int round = 1; round < Nr; ++round) {

SubBytes();// S盒变换

ShiftRows();// 行移位

MixColumns();// 列混合

AddRoundKey(round);

}

SubBytes();// S盒置换

ShiftRows();// 行移位

AddRoundKey(Nr);// 轮密钥加

for (int i = 0; i < (4 * Nb); i++) {

output[i] = this.State[i / Nb][i % Nb];

}

}

/**

* 解密过程

* @param inputs

* @param output

*/

public void Invcipher(byte[] input, byte[] output) {

this.State = new byte[4][Nb];

for (int i = 0; i < (4 * Nb); ++i) {

this.State[i / Nb][i % Nb] = input[i];

}// 初始化状态矩阵

AddRoundKey(Nr);// 轮密钥加

for (int round = Nr - 1; round > 0; round--) {

InvShiftRows();// 逆行移位

InvSubBytes();// 逆S盒置换

AddRoundKey(round);// 轮密钥加

InvMixColumns();// 逆列混合

}

InvShiftRows();// 逆行移位

InvSubBytes();// 逆S盒置换

AddRoundKey(0);// 轮密钥加

for (int i = 0; i < (4 * Nb); ++i) {

output[i] = this.State[i / Nb][i % Nb];

}// 输出结果

}

}

*************************AesCipherAndInvCipher.java**************** package AES;

import java.io.UnsupportedEncodingException;

import java.security.InvalidKeyException;

/**

* 辅助类处理明文字符输入字节数不匹配等问题

*/

public class AesCipherAndInvCipher {

byte[] key;// 密钥

private byte[] pt;// 明文字节数组

private byte[] ct;

private int mode;

private int Nb = 0;

private int dataLength;

private int blockSize = 4;// 分组大小32位,4bytes

public AesCipherAndInvCipher(byte[] kb) {

this.key = kb;

}

/**

* 加密

* @param kb

* @param plainText

* @return加密后密文字节数组

*/

private byte[] Eecrypt(String plainText, byte[] kb)

throws InvalidKeyException {

try {

pt = plainText.getBytes("UTF-8");// 获取明文字节数组

} catch (UnsupportedEncodingException e) {

System.out.println("不支持的编码类型!");

e.printStackTrace();

}

dataLength = pt.length;

mode = dataLength % blockSize;// 判断明文数组长度是否与分组长度匹配

ct = new byte[mode == 0 ? pt.length : dataLength / blockSize * 4 + 32];// 密文字节数组

Nb = dataLength / blockSize;

Aes a1 = new Aes(KEYSIZE.Bit128, kb, Nb);

Aes a2 = new Aes(KEYSIZE.Bit128, kb, 4);

Aes a3 = new Aes(KEYSIZE.Bit128, kb, 4);

if (mode == 0) {

a1.Cipher(pt, ct);

} else {

byte[] b1 = new byte[blockSize * Nb];// 匹配的部分

byte[] b2 = new byte[16];// 剩余部分

byte[] b3 = new byte[16];// 存明文长度

byte[] c1 = new byte[b1.length];

byte[] c2 = new byte[b2.length];

byte[] c3 = new byte[b3.length];

System.arraycopy(pt, 0, b1, 0, b1.length);

System.arraycopy(pt, Nb * blockSize, b2, 0, mode);

b3 = intToByteArray(dataLength);

a1.Cipher(b1, c1);

a2.Cipher(b2, c2);

a3.Cipher(b3, c3);

System.arraycopy(c1, 0, ct, 0, c1.length);

System.arraycopy(c2, 0, ct, b1.length, c2.length);

System.arraycopy(c3, 0, ct, b1.length + b2.length, c3.length);

}

return ct;

}

public byte[] EecryptToBytes(String plainText, byte[] kb)

throws InvalidKeyException {

byte[] ct = Eecrypt(plainText, kb);

return ct;

}

public String EecryptToString(String plainText, byte[] kb)

throws InvalidKeyException {

byte[] ct = Eecrypt(plainText, kb);

return BytesToString(ct);

}

/**

* 解密

*/

public String Decrypt(byte[] ct, byte[] kb) {

String s = "";

if (mode == 0) {

byte[] output = new byte[dataLength];

Aes a = new Aes(KEYSIZE.Bit128, kb, Nb);

a.Invcipher(ct, output);

try {

s = new String(output, "UTF-8");

System.out.println("解密:" + s);

} catch (UnsupportedEncodingException e) {

System.out.println("不支持的编码格式!");

e.printStackTrace();

}

} else {

byte[] length = new byte[16];

byte[] plainText1 = new byte[ct.length - 32];

byte[] plainText2 = new byte[16];

Aes a1 = new Aes(KEYSIZE.Bit128, kb, Nb);

Aes a2 = new Aes(KEYSIZE.Bit128, kb, 4);

Aes a3 = new Aes(KEYSIZE.Bit128, kb, 4);

byte[] c1 = new byte[ct.length - 32];

byte[] c2 = new byte[16];

byte[] c3 = new byte[16];

System.arraycopy(ct, ct.length - 16, c3, 0, c3.length);

System.arraycopy(ct, ct.length - 32, c2, 0, c2.length);

System.arraycopy(ct, 0, c1, 0, Nb * blockSize);

a3.Invcipher(c3, length);// 解密明文字节数组长度

a2.Invcipher(c2, plainText2);// 解密剩余的部分

a1.Invcipher(c1, plainText1);// 解密匹配的部分

int length1 = byteArrayToInt(length);

byte[] output = new byte[length1];

System.arraycopy(plainText1, 0, output, 0, plainText1.length);

System.arraycopy(plainText2, 0, output, plainText1.length, length1 - plainText1.length);

try {

s = new String(output, "UTF-8");

System.out.println("解密后明文:" + s);

} catch (UnsupportedEncodingException e) {

System.out.println("不支持的编码格式!");

e.printStackTrace();

}

}

return s;

}

public String Decrypt(String cryptText, byte[] kb) {

byte[] ct = StringToBytes(cryptText);

return Decrypt(ct, kb);

}

public String Decrypt(Byte[] ct, byte[] kb) {

return Decrypt(ct, kb);

}

/**

* int转化为Byte数组

*

* @param value

* @return

*/

private static byte[] intToByteArray(int value) {

byte[] b = new byte[16];

for (int i = 0; i < 4; i++) {

int offset = (b.length - 1 - i) * 8;

b[i] = (byte) ((value >>> offset) & 0xFF);

}

for (int i = 4; i < 16; i++) {

b[i] = 0;

}

return b;

}

/**

* byte数组转化为int

*

* @param b

* @return

*/

private static final int byteArrayToInt(byte[] b) {

byte[] b1 = new byte[4];

System.arraycopy(b, 0, b1, 0, 4);

return (b1[0] << 24) + ((b1[1] & 0xFF) << 16) + ((b1[2] & 0xFF) << 8) + (b1[3] & 0xFF);

}

/**

* 显示字节数组

*

* @param b

*/

public static void DisplayAsBytes(byte[] b) {

for (int i = 0; i < b.length; i++) {

String hex = Integer.toHexString(b[i] & 0xFF);

if (hex.length() == 1) {

hex = '0' + hex;

}

System.out.print(hex.toUpperCase() + " ");

}

System.out.println();

}

private static String BytesToString(byte[] b) {

String s = "";

for (int i = 0; i < b.length; i++) {

String hex = Integer.toHexString(b[i] & 0xFF);

if (hex.length() == 1) {

hex = '0' + hex;

}

s += hex;

}

return s;

}

private static byte[] StringToBytes(String cryptText) { byte[] b = new byte[cryptText.length() / 2];

int[] a = new int[cryptText.length()];

for (int i = 0; i < cryptText.length(); ++i) {

String s = cryptText.substring(i, i + 1);

if (s.equals("a"))

a[i] = 10;

else if (s.equals("b"))

a[i] = 11;

else if (s.equals("c"))

a[i] = 12;

else if (s.equals("d"))

a[i] = 13;

else if (s.equals("e"))

a[i] = 14;

else if (s.equals("f"))

a[i] = 15;

else

a[i] = Integer.valueOf(s);

}

for (int i = 0; i < cryptText.length() / 2; i++) {

b[i] = (byte) (a[2 * i] * 16 + a[2 * i + 1]);

}

return b;

}

}

*************************generateKey.java********************** package AES;

import java.io.UnsupportedEncodingException;

import java.security.InvalidKeyException;

import java.util.Random;

public class generateKey {

private static byte[] key;

/**

* 随机生成key

* @param keySize

* @return

* @throws InvalidKeyException

*/

public static byte[] generateRandomKey(int keySize)

throws InvalidKeyException {

if (keySize == KEYSIZE.Bit128 | keySize == KEYSIZE.Bit192

| keySize == KEYSIZE.Bit256) {

key = new byte[keySize / 8];

for (int i = 0; i < keySize / 8; i++) {

Random r = new Random();

int tempByte = r.nextInt() * 255;

key[i] = (byte) tempByte;

}

return key;

} else {

throw new InvalidKeyException("密钥长度错误,正确长度为128,192或者256位!");

}

}

/**

* 根据字符串生成key

* @param keyStr

* @return

*/

public static byte[] generateKeyFromString(String keyStr) {

byte[] tempkey = null;

try {

tempkey = keyStr.getBytes("UTF-8");

} catch (UnsupportedEncodingException e) {

System.out.println("不支持的编码类型!");

e.printStackTrace();

}

if (tempkey.length < 128) {

key = new byte[16];

byte lastByte = tempkey[tempkey.length - 1];

for (int i = tempkey.length; i < 16; i++) {

key[i] = gfmultby02(lastByte);

lastByte = key[i - 1];

}

} else if (tempkey.length > 128 && tempkey.length < 192) {

key = new byte[24];

byte lastByte = tempkey[tempkey.length - 1];

for (int i = tempkey.length; i < 24; i++) {

key[i] = gfmultby02(lastByte);

lastByte = key[i - 1];

}

} else if (tempkey.length > 192 && tempkey.length < 256) {

key = new byte[32];

byte lastByte = tempkey[tempkey.length - 1];

for (int i = tempkey.length; i < 32; i++) {

key[i] = gfmultby02(lastByte);

lastByte = key[i - 1];

}

} else if (tempkey.length > 256) {

key = new byte[32];

System.arraycopy(tempkey, 0, key, 0, 32);

} else {

key = tempkey;

}

return key;

}

public int getKeyLength() {

return key.length;

}

private static byte gfmultby02(byte b) {

if (((b >> 7) & 0x01) == 0) // !!!!!!!这里比较大小的时候注意符号位

return (byte) (b << 1);

else

return (byte) ((b << 1) ^ (byte) 0x1b);

// 消除符号位可以用b&0xff

}

}

*************************KEYSIZE.java*************************

package AES;

/**

* 密钥长度

*

* @author卢富毓

*/

public class KEYSIZE {

public static final int Bit128 = 128;// 128位

public static final int Bit192 = 192;// 192位

public static final int Bit256 = 256;// 256位

}

*************************testAes.java*************************

package AES;

import java.security.InvalidKeyException;

public class testAes {

public static void main(String[] args) {

byte[] plainText = new byte[] { 0x11, 0x11, 0x22, 0x33, 0x44, 0x55,

0x66, 0x77, (byte) 0x88, (byte) 0x99, (byte) 0xaa, (byte) 0xbb,

(byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff, 0x00, 0x11,// 0x22,

// 0x33,0x44,

// 0x55,

0x66, 0x77 };// 明文

byte[] cipherText = new byte[20];

byte[] decipheredText = new byte[20];

byte[] keyBytes = null;

try {

keyBytes = generateKey

.generateKeyFromString("AES1wrwe2432v112wwwwwwwwwwwwwwwwwwww@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@wwwwwwwwwwwwwwwwwwwwwww34@#%$1234fffffffffffffffffffffff");

} catch (Exception e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

Aes a = new Aes(KEYSIZE.Bit192, keyBytes, 5);

System.out

.println("***********************测试1****************************");

byte[] key1 = null;

try {

key1 = generateKey.generateRandomKey(KEYSIZE.Bit128);

} catch (InvalidKeyException e1) {

e1.printStackTrace();

}

AesCipherAndInvCipher aes = new AesCipherAndInvCipher(key1);

byte[] dt = null;

String ss = null;

try {

dt = new byte[16];

dt = aes.EecryptToBytes("AES11212121212121", keyBytes);

ss = aes.EecryptToString("AES1wrwe2432v1343", keyBytes);

System.out.println("明文1:AES11212121212121");

System.out.println("明文2:AES1wrwe2432v1343");

System.out.println("字节式加密,密文:" + new String(dt));

System.out.println("字符串式加密,密文:" + ss);

} catch (InvalidKeyException e) {

e.printStackTrace();

}

aes.Decrypt(dt, keyBytes);

aes.Decrypt(ss, keyBytes);

System.out

.println("\n*************************测试

2*****************************");

AesCipherAndInvCipher aes1 = new AesCipherAndInvCipher(key1);

byte[] dt1 = null;

try {

// dt = new byte[16];

String plainText1 = "uuid=FSFASW24S-0342-FEW3-3F33-F44F2SE523432D";

dt1 = aes1.EecryptToBytes(plainText1, keyBytes);

System.out.println("明文:" + plainText1);

System.out.println("字节式加密,密文:" + new String(dt1));

} catch (InvalidKeyException e) {

e.printStackTrace();

}

aes1.Decrypt(dt1, keyBytes);

}

/**

* 显示16进制

* @param b

*/

public static void DisplayAsBytes(byte[] b) {

for (int i = 0; i < b.length; i++) {

String hex = Integer.toHexString(b[i] & 0xFF);

if (hex.length() == 1) {

hex = '0' + hex;

}

System.out.print(hex.toUpperCase() + " ");

}

System.out.println();

}

}

非对称密码体制的认证与对称密码体制的加密

非对称密码体制的认证和对称密码体制的加密 仵惠婷 22620139407 摘要:本文主要介绍在安全网络通信过程中:用非对称密码体制即公钥密码来进行通信双方的身份认证,以确保发送方是真的发送方,接收方是真的接收方;用对称密码体制对通信双方交互的通信数据进行加密的安全网络通信方案。非对称密码体制方案较对称密码体制方案处理速度慢,因此,通常把非对称密钥与对称密钥技术结合起来实现最佳性能。即用非对称密钥技术在通信双方之间传送会话密钥,而用会话密钥来对实际传输的数据加密解密。另外,非对称加密也用来对对称密钥进行加密。 关键词:非对称密码体制;认证;对称密码体制;加密; 1.引言 在要求安全的网络环境下通信双方首先要确认对方的身份是否属实,以防止伪造身份的恶意程序向正常服务发起服务请求,以防止恶意程序截获交付给正常客户程序的正常服务。然后要在整个通信过程中对通信双方交互的通信数据进行加密,以防止即使数据被泄露或者截获也不易被恶意程序篡改或伪造等。在现有密码技术条件下,应用非对称密码体制对通信双方进行身份认证,应用对称密码体制对通信数据进行加密的方案可谓设计精妙。 2.非对称密码体制的认证 非对称密码体制可以对信息发送与接收人的真实身份的验证、对所发出/接收信息在事后的不可抵赖以及保障数据的完整性是现代密码学主题的另一方面。 首先要介绍的是证书和CA。其中证书是将公钥和公钥主人名字放在一起被CA权威机构的私钥签名,所以大家都认可这个证书,而且知道了公钥的主人。而CA就是这个权威机构,也拥有一个证书,也有私钥,所以它有签字的能力。网上的公众用户通过验证CA的签字从而信任CA,任何人都应该可以得到CA的证书,用以验证它所签发的证书。如果一个用户想鉴别另一

第三章 对称密码体制

第三章对称密码体制 计算机科学与技术学院 对称密码体制 §1、对称密码体制简介 §2、典型的对称密码算法 §3、数据加密标准DES §4、高级数据加密标准AES §5、密码分析 §6、分组密码的工作模式 §7、流密码简介 2

3 §对称密码体制(私钥):加密密钥和解密密钥相同,且都需要保密。 ?优点:加密算法比较简便、高效、密钥简短,对方破译极其困难,且经受住时间的检验和攻击;?缺点:密钥必须通过安全的途径传送。 ?系统的机密性主要取决于密钥的安全性。 ?加密的方式: §按字符逐位加密(流密码) §将明文消息分组(分组密码) ?常用算法:DES ?适用范围:数据加密、消息认证1、对称密钥体制简介

2、典型的对称加密算法 1、DES加密算法 §定义:DES 全称为Data Encryption Standard即数据加密算法,它是IBM公司于1975年研究成功并公开发表的,1977年,美国把DES用于国家非保密机关。 §DES是一种采用传统加密方法的分组密码。它的算法是对称的,既可用于加密又可用于解密。 §基本思想:DES对64比特二进制数据加密,产生64比特等长的密文数据。使用的密钥为64比特,实际密钥长度为56比特(有8比特用于奇偶校验)。 5 典型的对称加密算法 §2、IDEA算法 ?IDEA(International Data Encryptdri Algorithm), 即“国际数据加密算法”。 ?IDEA采用基于“相异代数群上的混合运算”的设计思想,其算法的明、密文组位长度为64位,密钥长度为128位。 §3、FEAL-8密码 ?FEAL密码算法家族是日本NTT(日本电报电话公司 )设计的。密钥组位长度为64比特,明、密文组位长度 为64比特。作为一种分组密码,与DES相比,其增加了 每一轮迭代的算法强度,因此可以通过减少迭代次数而 提高运算速度。 6

对称密码体制

云南大学数学与统计学实验教学中心实验报告 一、实验目的: 通过实验掌握AES加密实验的构造算法,以及其重要思想。 二、实验内容: 查阅资料,实现AES密码体制的编码算法、译码算法、子密钥生成算法 三、实验环境 Win7、Eclipse 四、实验过程(请学生认真填写): 实验过程、结果以及相应的解释: 1. 预备知识 密码学中的高级加密标准(Advanced Encryption Standard,AES),是一种对称加密的方法。 本实验使用Java平台来编写的,虽然在java中已经很好的实现了AES等安全机制,但是为了了解如何实现,还是写了一个AES加密的java程序。 2. 实验过程 A、原理分析: 大多数AES计算是在一个特别的有限域完成的。 AES加密过程是在一个4×4的字节矩阵上运作,这个矩阵又称为“体(state)”,其初值就 是一个明文区块(矩阵中一个元素大小就是明文区块中的一个Byte)。(Rijndael加密法因支 持更大的区块,其矩阵行数可视情况增加)加密时,各轮AES加密循环(除最后一轮外)均 包含4个步骤: AddRoundKey —矩阵中的每一个字节都与该次回合金钥(round key)做XOR运算;每个子 密钥由密钥生成方案产生。 SubBytes —通过一个非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。 ShiftRows —将矩阵中的每个横列进行循环式移位。 MixColumns —为了充分混合矩阵中各个直行的操作。这个步骤使用线性转换来混合每列的 四个字节。 最后一个加密循环中省略MixColumns步骤,而以另一个AddRoundKey取代。 B、具体代码如下: //如6.2,若是将每一行看做是一个对象的话 //具体实现的整体结构思想如此下图

对称密钥密码系统

对称密钥密码系统 2000多年以前,罗马国王Julius Caesar使用过现今被称为“凯撒密码”的加密算法。此加密算法其实是“移位密码”算法的一个特例。由于移位密码安全性不高,使用穷举爆力技术很容易将其破解,于是人们发明了“代换密码”。而移位密码其实是代换密码的一个子集。虽然代换密码安全性有所提高,使用穷举爆力技术较难破解,然而使用统计密码分析技术却可以很容易地破解代换密码。 到了几百年前,有人发明了“置换密码”有时也叫“换位密码”,之后现代密码技术开始出现。很多人把Claude Shannon誉为现代密码学之父,他提出了“扩散”和“混淆”来构造密码体制的基本要素。这种加密技术可以有效的挫败使用统计分析技术来破解密码。 1973年,Horst Feistel公开了他的“Feistel密码”,这是第一个体现密码之父Shannon思想的密码系统。目前,几乎所有的对称密码系统都使用了Feistel密码的设计特征。 1973年,(美)国家标准局(NBS),即现在的(美)国家标准技术研究所(NIST)公布了征求国家密码标准的提案,人们建议了许多的密码系统。 1977年7月,NBS经过对众多的密码系统进行评估后,采纳了IBM在20世纪60年代(1960s)研制出来的一个密码系统作为数据加密标准(DES),此系统是由Horst Feistel领导的一个研究组研制出来的。这个密码系统基于一个称为LUCIFER[Fic73]的密码系统。LUCIFER密码系统本质上是Feistel密码的一个推广。 1983年、1988年和1993年,DES再度被认定为(美)国家标准。 1997年,RSA实验室发布了一个以10000美元作为酬金的挑战:寻找一个前面带有一个已知明文块的密文的DES密钥。由Roche Verse牵头的一个工程小组动用了70000多台通过因特网连接起来的计算机系统,使用穷举爆力攻击程序大约花费96天的时间找到了正确的DES密钥。意识到DES已经快完成它的历史使命,NIST于1997年1月宣布了一项选择一个用作高级加密标准(AES)的候选算法的计划:这个新的标准的将取代DES。

对称密钥密码

1引言 计算机的发展给人类带来了前所未有的便利,以计算机信息技术为手段的企业信息化建设,已成为企业必不可少的部分。计算机CAD技术高速度、高精度和高效等的优点,已经逐步取代手工设计,广泛应用于产品设计工作中。CAD图纸,在任何时候,都是一个企业的命脉。在使用SolidWorks等软件绘制图纸的过程中,作为企业是否经常会考虑:我们厂刚刚设计出来的新产品,怎么市场上别的牌子的产品也已经上市啦?技术人员的流动,是否会同时有图纸的流动?我们花了几十万买的图纸,怎么隔壁的那个厂子图纸和我们的一样呢?我们的光驱、软驱、U盘接口都封掉了,可是图纸怎么还是传出去啦?解决这些问题的一种有效方法就是使用现代密码技术,加密技术是保障信息安全的最基本的、最核心的技术措施。对CAD图纸进行加密应该是一种比较合适的安全保密措施 2密码技术 2.1基本概念 密码学是研究编制密码和破译密码的技术科学。密码在早期仅对文字或数码进行加、脱密变换,随着通信技术的发展,对语音、图像、数据等都可实施加、脱密变换。随着先进科学技术的应用,密码学已成为一门综合性的尖端技术科学。它与语言学、数学、电子学、声学、信息论、计算机科学等有着广泛而密切的联系。密码就是一组含有参数K的变换E。设已知信息M,通过变换E得到密文C。即C=EK(M)这个过程称之为加密,参数K称为密钥。

2.1.1传统密码学 自从有了人类社会就有了信息交流,特别是出现了战争,为了信息交流的安全,就出现了密码技术。从古代到16世纪末由于这个时期生产力低下,产生的许多密码体制都是可用纸笔或者简单的器械实现加密/解密的,这个时期的密码体制主要有两大类:一类是换位密码体制,另一类是代替密码体制。从二十世纪初到20世纪50年代末,为了适应密码通信的需要,密码设计者设计出了一些采用复杂的机械和电动机械设备实现信息加密/解密操作,他们代替了繁重的手工作业方式,在战争中发挥了重要的作用。转轮密码机是这一时期的杰出代表。 2.1.2现代密码学 对称密钥密码体制又称为单密钥密码体制或秘密密钥密码体制。这种密码体制的加密密钥和解密密钥相同,或者虽然不相同,但可由其中的任意一个可以和容易地推导出另一个。传统的密码学都是属于对称密钥密码体制。现在,在传统密码学地基础上对称密码体制也有了新地发展,像序列密码,分组密码,还有对称密钥密码体制的典型代表:数据加密标准DES和高级数据加密标准AES。非对称密钥密码体制又称为双密钥密码体制或公开密钥密码体制。这种密码体制的加密/解密操作分别使用两个不同地密钥,并且不可能由加密密钥推导出解密密钥。采用非对称密钥密码体制的每个用户都有一对相互关联而又彼此不同地密钥,使用其中的一个密钥加密的数据,不能使用该密钥自身进行解密,而只能使用对应的另一个密钥进行解密。在这一对密钥中,其中一个密钥称为公钥,它可以公开并通过公开的信道发给任何一位想与自己通信的另

1.对称加密体制的优缺点

1.对称加密体制的优缺点: 优点:加密速度快,保密度高。 缺点: 1.密钥是保密通信的关键,如何才能把密钥安全送到收信方是对称加密体制的突出问 题。 2. n个合作者,就需要n各不同的密钥,使得密钥的分发复杂。 3.通信双方必须统一密钥。 4.难以解决数字签名认证问题。不适合网络邮件加密需要。 DES是采用传统换位与置换的加密方法的分组密码系统。 2.非对称加密体制的优缺点: 缺点: 加密算法复杂,加密和解密的速度比较慢。 优点: 1.公钥加密技术与对称加密技术相比,其优势在于不需要共享通用的密钥。 2.公钥在传递和发布过程中即使被截获,由于没有与公钥相匹配的私钥, 截获的公钥对入侵者没有太大意义。 3.密钥少便于管理,N个用户通信只需要N对密钥。 4.密钥分配简单,加密密钥分发给用户,而解密密钥由用户自己保留。 3.数字签名和加密的区别 数字签名采用公开密钥算法实现,数字签名与通常的数据加密算法作用是不同的,它们的实现过程与使用的密钥不同。 数字签名使用的是发送方的密钥对,发送方用自己的私有密钥进行加密,接收方用发送方的公开密钥进行解密。数字签名是一个一对多关系:任何拥有发送方公开密钥得人都可验证数字签名的正确性。数字签名是为了证实信息确实是由某个用户发送,对网络中是否有人看到该信息并不关心。 数据加密使用的是接受方的密钥对,发送方用接收方的公开密钥进行加密,接受方用自己的私有密钥进行解密。加密是一个多对一的关系:任何知道接受方公开密钥的人都可以向接收方发送加密信息,只有拥有接收方私有密钥的人才能对信息解密。 一个用户通常有两个密钥对,一个用来对数字签名进行加密解密,一个用来对私密密钥进行加密解密。 4.RSA算法中,素数p=7,q=11,加密密钥e=7,计算解密密钥d 解:N=pq=7*11=77 φ(n)=(p-1)(q-1)=6*10=60 根据公式d× e ≡ 1 (mod (p-1)(q-1)) 又e=7,所以7*d≡ 1 (mod 60)。。即7d mod 60 = 1。 7x43=301 301除以6刚好余1. 所以d=43 5.已知RSA算法中的两个素数P=11,Q=17,公钥部分E=13,明文M=9, 请计算出私钥部分的D和密文C的值是多少?(c=25 d=37)

对称密码体制及其算法研究

第23卷第6期 齐 齐 哈 尔 大 学 学 报 Vol.23,No.6 2007年11月 Journal of Qiqihar University Nov.,2007 对称密码体制及其算法研究 于学江 (齐齐哈尔大学计算机与控制工程学院,黑龙江 齐齐哈尔 161006) 摘要:密码算法是实现网络信息安全的基础,本文对现代密钥密码算法及体系进行了研究,介绍了对称密码体制 与非对称密码体制,重点分析了对称密码体制中分组密码与序列密码算法的原理、性质,比较了分组密码与序列 密码的不同应用特性。 关键词:对称密码体制;分组密码算法;序列密码算法 中图分类号:TP309.7 文献标识码:A 文章编号:1007-984X(2007)06-0038-03 1 现代密码体制 现代密码体制的研究基本上沿着两个方向进行,即对称密码体制和非对称密码体制。对称密码体制又称单钥或私钥密码体制。在对称密码体制中,加密密钥和解密密钥是一样的或彼此之间容易相互确定,因此对称密码体制的安全性主要取决于密钥的安全性。按加密方式不同,对称密码算法可分为分组密码和序列密码。分组密码是将消息进行分组,并按组加密。而序列密码是利用密钥序列对明文进行逐比特加密从而产生密文。 非对称密钥密码体制,又称为双钥或公钥密码体制。在非对称密钥密码体制中,加密密钥不同于解密密钥,加密密钥公之于众,谁都可以使用。解密密钥只有解密人自己知道,分别称为公开密钥和秘密密钥。 2 对称密码算法 2.1 分组密码 分组密码的基本原理是将明文分成固定长度的组(块),如64 bit一组,用同一密钥和算法对每一块加密,输出也是固定长度的密文。目前最常用的对称加密算法有数据加密标准的DES、新一代分组加密标准AES、国际数据加密算法IDEA、Blowfish加密算法等,他们的加密原理都是Feistel分组密码结构。其中以DES 算法最为著名,是到目前为止使用最广的算法。 2.1.1 DES密码算法 DES 算法是将64 bit 的明文初始重排后,在密钥控制下进行16次复杂的非线性变换,得到64 bit 的预输出,接着再对预输出经过一次逆初始化重排。整个算法是代替法和换位法的组合,共叠代16层。该算法分3个阶段实现: 1)对输入的明文分组m 进行固定的初始置换函数IP ,该初始置换可表示为 000)(R L m IP m == (1) 2)计算函数f 的16次迭代运算,即 1?=i i R L ),(11i i i i K R f L R ??⊕= )16,,2,1("=i (2) 其中i k 是48位的子密钥,子密钥是作为密钥k 的函数而计算出的。f 称为“S 盒函数” ,是一个替代密码。这个运算的特点是交换两半分组,这一轮的左半分组输入是上一轮的右半分组输出。交换运算是一 收稿日期:2007-07-17 作者简介:于学江(1964-),男,黑龙江齐齐哈尔人,副教授,大学本科,主要从事数学教育、算法分析设计等研究,Email:yuxjph@https://www.360docs.net/doc/2118506021.html,。

公钥密码和对称密码

密码学中两种常见的密码算法为对称密码算法(单钥密码算法)和非对称密码算法(公钥密码算法)。 对称密码算法有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,反过来也成立。在大多数对称算法中,加密解密密钥是相同的。这些算法也叫秘密密钥算法或单密钥算法,它要求发送者和接收者在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都能对消息进行加密解密。只要通信需要保密,密钥就必须保密。对称算法的加密和解密表示为: Ek(M)=C Dk(C)=M 对称算法可分为两类。一次只对明文中的单个位(有时对字节)运算的算法称为序列算法或序列密码。另一类算法是对明文的一组位进行运算,这些位组称为分组,相应的算法称为分组算法或分组密码。现代计算机密码算法的典型分组长度为64位――这个长度大到足以防止分析破译,但又小到足以方便作用。 这种算法具有如下的特性: Dk(Ek(M))=M 常用的采用对称密码术的加密方案有5个组成部分(如图所示) l)明文:原始信息。 2)加密算法:以密钥为参数,对明文进行多种置换和转换的规则和步骤,变换结果为密文。 3)密钥:加密与解密算法的参数,直接影响对明文进行变换的结果。 4)密文:对明文进行变换的结果。 5)解密算法:加密算法的逆变换,以密文为输入、密钥为参数,变换结果为明文。 对称密码术的优点在于效率高(加/解密速度能达到数十兆/秒或更多),算法简单,系统开销小,适合加密大量数据。 尽管对称密码术有一些很好的特性,但它也存在着明显的缺陷,包括: l)进行安全通信前需要以安全方式进行密钥交换。这一步骤,在某种情况下是可行的,但在某些情况下会非常困难,甚至无法实现。 2)规模复杂。举例来说,A与B两人之间的密钥必须不同于A和C两人之间的

网络安全中基于传统对称密码体制的密钥管理

网络安全中基于传统对称密码体制的密钥管理 摘要 本文主要介绍了基于传统对称密码体制下的一种密钥分配方案。它将整个系统中的密钥从低到高分成三个等级——初级密钥、二级密钥和主机主密钥。低级密要不会以明文的形式出现,而是以受高级密钥加密的形式传输和保存。高级密钥存放在一种专有密码装置(硬件)的工作寄存器中(该寄存器的容只能设置不能访问),并且相关的密码转换操作均在专有密码装置中进行,这样便保证了密钥装置之外永不一明文的形式出现。从而较好的提供了一种安全的密钥管理方案。 1.介绍 根据近代密码学的观点,密码系统的安全应只取决于密钥的安全,而不取决于对算法的。在计算机网络环境中,由于用户和节点很多,需要使用大量的密钥。密钥的数量如此之大,而且又要经常更换,其产生、存贮、分配是极大的问题。如无一套妥善的管理方法,其困难性和危险性是可想而知的。 以下的讨论基于这样一个事实:计算机网络中的各个节点或者是主机或者是终端。 为了简化密钥的管理工作,我们采用密钥分级策略。我们将密钥分成初级密钥、二级密钥和主机主密钥三个级别。 1)初级密钥 用于加解密数据的密钥称为初级密钥,记为K。初级密钥可由系统应用实体请求通过硬件或软件方式自动产生,也可以由用户自己提供。初级密钥仅在两个应用实体交换数据时才存在,它的生存周期很短,通常只有几分钟。 为了安全,初级密钥必须受更高一级的密钥的保护,直至它的生存周期结束为止。 一般而言,初级密钥为相互通信的两个进程所共享,在主机或终端上会同时存在多个初级密钥。 2)二级密钥 二级密钥用以加密保护初级密钥,记作KN。二级密钥的生存周期一般 较长,它在较长时间里保持不变。 3)主机主密钥 主机主密钥是这一管理方案中的最高钥,记作KM,用于对主机系 统的初级密钥和二级密钥提供保护。主机主密钥的生存周期很长。 在一个网络系统中由主机和终端等多种需要使用密钥的实体,只有针对 不同性质的实体配备不同的密钥,并对不同的密钥采取不同的保护才能 方便密钥的管理。我们可以采用下面的密钥配置方案。

相关文档
最新文档