JAva-信頼性の高い安全なチャネルを非安全なネットワーク上に確立(3/3)
このブログの最初の2つのセクション(1/3,2/3)では、安全でないネットワーク環境の下で双方のアイデンティティを相互に認証する方法(信頼できる接続を確立する方法)と、それに基づいて信頼できる鍵交渉(DHアルゴリズム)を紹介しています.
このセクションでは、チャネル上に流れるデータを、協議された鍵を使用して暗号化する方法について説明します.対称鍵のアルゴリズムとしてAESを使用します.鍵強度:128ビットです.このプロセスは、次の2つのステップに簡単にまとめることができます.
は、ネゴシエートされたkeyを使用して、暗号化および復号化に使用できるAes Cipherを作成する. このcipherを使用してbyte配列を暗号化および復号化する.
コードを直接付けましょう.
いくつかのツールクラスのコードは貼らない.
このセクションでは、チャネル上に流れるデータを、協議された鍵を使用して暗号化する方法について説明します.対称鍵のアルゴリズムとしてAESを使用します.鍵強度:128ビットです.このプロセスは、次の2つのステップに簡単にまとめることができます.
コードを直接付けましょう.
/**
* AES 128bit
*
* @author atlas
* @date 2012-9-18
*/
public class AESCipher {
private static final int bsize = 16;
private static final int ivsize = 16;
private Cipher dCipher;
private Cipher eCipher;
private AESCipher(Cipher dCipher, Cipher eCipher) {
this.eCipher = eCipher;
this.dCipher = dCipher;
}
public static AESCipher getInstance(byte[] key) throws CryptoException {
String pad = "PKCS5Padding";
try {
byte[] tmpKey = ChecksumUtil.getChecksumAsBytes("md5", key);
byte[] tmpIV = new byte[ivsize];
if (key.length <= ivsize) {
System.arraycopy(key, 0, tmpKey, 0, key.length);
} else if (key.length > ivsize) {
System.arraycopy(key, 0, tmpIV, 0, tmpIV.length);
}
SecretKeySpec keyspec = new SecretKeySpec(tmpKey, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(tmpIV);
Cipher dcipher = Cipher.getInstance("AES/CBC/" + pad);
Cipher ecipher = Cipher.getInstance("AES/CBC/" + pad);
ecipher.init(Cipher.ENCRYPT_MODE, keyspec, ivSpec);
dcipher.init(Cipher.DECRYPT_MODE, keyspec, ivSpec);
return new AESCipher(dcipher, ecipher);
} catch (Exception e) {
throw new CryptoException("initializing AESCipher fail.", e);
}
}
/**
*
* @param str
* @return
* @throws CryptoException
*/
public String encrypt(String str) throws CryptoException {
try {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes("UTF8");
// Encrypt
byte[] enc = this.eCipher.doFinal(utf8);
// Encode bytes to hex string
return StringUtils.bytesToHex(enc);
} catch (Exception e) {
throw new CryptoException("encrypt failed.", e);
}
}
public String decrypt(String str) throws CryptoException {
try {
byte[] dec = StringUtils.hexToBytes(str);
// Decrypt
byte[] utf8 = this.dCipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (Exception e) {
throw new CryptoException("decrypt failed.", e);
}
}
public byte[] encrypt(byte[] message) throws CryptoException {
try {
// Encrypt
return this.eCipher.doFinal(message);
} catch (Exception e) {
throw new CryptoException("encrypt failed.", e);
}
}
/**
* ,input buffer output
* buffer byte , output , padding。
* padding {@link #getBsize() }-1
*
* @param input
* buffer
* @param inputOffset
* input buffer ( 0 )
* @param inputLen
* , (input.length-inputOffset).
* @param output
* buffer。
* @param outputOffset
* buffer 。
* @return output
*
* @throws ShortBufferException
* output buffer ,
*/
public int encrypt(byte[] input, int inputOffset, int inputLen,
byte[] output, int outputOffset) throws CryptoException {
try {
return eCipher.doFinal(input, inputOffset, inputLen, output,
outputOffset);
} catch (Exception e) {
throw new CryptoException("encryption failed", e);
}
}
/**
* ,input buffer output buffer byte 。
*
* @param input
* buffer
* @param inputOffset
* input buffer ( 0 )
* @param inputLen
* , (input.length-inputOffset).
* @param output
* buffer。
* @param outputOffset
* buffer 。
* @return output
* @throws ShortBufferException
* output buffer ,
*/
public int decrypt(byte[] input, int inputOffset, int inputLen,
byte[] output, int outputOffset) throws CryptoException {
try {
return dCipher.doFinal(input, inputOffset, inputLen, output,
outputOffset);
} catch (Exception e) {
throw new CryptoException("decryption failed", e);
}
}
/**
* padding
*
* @param len
* @return
*/
public int pad(int len) {
return eCipher.getOutputSize(len) - len;
}
public byte[] decrypt(byte[] message) throws CryptoException {
try {
// Decrypted
byte[] decrypted = this.dCipher.doFinal(message);
return decrypted;
} catch (Exception e) {
throw new CryptoException("decrypt failed.", e);
}
}
}
いくつかのツールクラスのコードは貼らない.