>Java >java지도 시간 >Java에서 AES 암호화 알고리즘을 구현하는 간단한 예 공유

Java에서 AES 암호화 알고리즘을 구현하는 간단한 예 공유

高洛峰
高洛峰원래의
2017-01-24 11:09:131589검색

암호학에서의 Rijndael 암호화 방식이라고도 알려진 Advanced Encryption Standard(영어: Advanced Encryption Standard, 약어: AES)는 미국 연방 정부에서 채택한 블록 암호화 표준입니다. 이 표준은 원래 DES를 대체하는 데 사용되었으며 많은 당사자에서 분석되었으며 전 세계적으로 널리 사용됩니다.
대부분의 AES 계산은 특수 유한 영역에서 수행됩니다.
AES 암호화 프로세스는 4×4바이트 행렬에서 작동합니다. 이 행렬은 "상태"라고도 하며 초기 값은 일반 텍스트 블록입니다(행렬의 요소 크기는 일반 텍스트 블록 A바이트). (Rijndael 암호화 방법은 더 큰 블록을 지원하므로 매트릭스 행 수를 적절하게 늘릴 수 있습니다.) 암호화 시 각 AES 암호화 주기(마지막 라운드 제외)에는 4단계가 포함됩니다.

AddRoundKey — 매트릭스는 라운드 키와 XOR됩니다. 각 하위 키는 키 생성 방식에 의해 생성됩니다.

SubBytes - 비선형 대체 기능을 통해 조회 테이블을 사용하여 각 바이트를 해당 바이트로 대체합니다.

ShiftRows — 행렬의 각 행을 순환적으로 이동합니다.

MixColumns — 행렬의 각 행의 작업을 완전히 혼합하기 위해. 이 단계에서는 선형 변환을 사용하여 각 열의 4바이트를 혼합합니다.

마지막 암호화 루프에서 MixColumns 단계를 생략하고 다른 AddRoundKey로 교체합니다.

Java 기본 구현:

package com.stone.security; 
  
import java.util.Arrays; 
  
import javax.crypto.Cipher; 
import javax.crypto.KeyGenerator; 
import javax.crypto.SecretKey; 
import javax.crypto.spec.IvParameterSpec; 
  
/** 
 * AES 算法 对称加密,密码学中的高级加密标准 2005年成为有效标准 
 */
public class AES { 
 static Cipher cipher; 
 static final String KEY_ALGORITHM = "AES"; 
 static final String CIPHER_ALGORITHM_ECB = "AES/ECB/PKCS5Padding"; 
 static final String CIPHER_ALGORITHM_CBC = "AES/CBC/PKCS5Padding"; 
/** 
 * AES/CBC/NoPadding 要求 
 * 密钥必须是16位的;Initialization vector (IV) 必须是16位 
 * 待加密内容的长度必须是16的倍数,如果不是16的倍数,就会出如下异常: 
 * javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes 
 * 
 * 由于固定了位数,所以对于被加密数据有中文的, 加、解密不完整 
 * 
 * 可 以看到,在原始数据长度为16的整数n倍时,假如原始数据长度等于16*n,则使用NoPadding时加密后数据长度等于16*n, 
 * 其它情况下加密数据长 度等于16*(n+1)。在不足16的整数倍的情况下,假如原始数据长度等于16*n+m[其中m小于16], 
 * 除了NoPadding填充之外的任何方 式,加密数据长度都等于16*(n+1). 
 */
 static final String CIPHER_ALGORITHM_CBC_NoPadding = "AES/CBC/NoPadding"; 
  
 static SecretKey secretKey; 
   
 public static void main(String[] args) throws Exception { 
 method1("a*jal)k32J8czx囙国为国宽"); 
 method2("a*jal)k32J8czx囙国为国宽"); 
 method3("a*jal)k32J8czx囙国为国宽"); 
   
 method4("123456781234囙为国宽");// length = 16 
 method4("12345678abcdefgh");// length = 16 
   
 } 
  
 /** 
 * 使用AES 算法 加密,默认模式 AES/ECB 
 */
 static void method1(String str) throws Exception { 
 cipher = Cipher.getInstance(KEY_ALGORITHM); 
 //KeyGenerator 生成aes算法密钥 
 secretKey = KeyGenerator.getInstance(KEY_ALGORITHM).generateKey(); 
 System.out.println("密钥的长度为:" + secretKey.getEncoded().length); 
   
 cipher.init(Cipher.ENCRYPT_MODE, secretKey);//使用加密模式初始化 密钥 
 byte[] encrypt = cipher.doFinal(str.getBytes()); //按单部分操作加密或解密数据,或者结束一个多部分操作。 
   
 System.out.println("method1-加密:" + Arrays.toString(encrypt)); 
 cipher.init(Cipher.DECRYPT_MODE, secretKey);//使用解密模式初始化 密钥 
 byte[] decrypt = cipher.doFinal(encrypt); 
 System.out.println("method1-解密后:" + new String(decrypt)); 
   
 } 
  
 /** 
 * 使用AES 算法 加密,默认模式 AES/ECB/PKCS5Padding 
 */
 static void method2(String str) throws Exception { 
 cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB); 
 //KeyGenerator 生成aes算法密钥 
 secretKey = KeyGenerator.getInstance(KEY_ALGORITHM).generateKey(); 
 System.out.println("密钥的长度为:" + secretKey.getEncoded().length); 
   
 cipher.init(Cipher.ENCRYPT_MODE, secretKey);//使用加密模式初始化 密钥 
 byte[] encrypt = cipher.doFinal(str.getBytes()); //按单部分操作加密或解密数据,或者结束一个多部分操作。 
   
 System.out.println("method2-加密:" + Arrays.toString(encrypt)); 
 cipher.init(Cipher.DECRYPT_MODE, secretKey);//使用解密模式初始化 密钥 
 byte[] decrypt = cipher.doFinal(encrypt); 
 System.out.println("method2-解密后:" + new String(decrypt)); 
   
 } 
  
 static byte[] getIV() { 
 String iv = "1234567812345678"; //IV length: must be 16 bytes long 
 return iv.getBytes(); 
 } 
  
 /** 
 * 使用AES 算法 加密,默认模式 AES/CBC/PKCS5Padding 
 */
 static void method3(String str) throws Exception { 
 cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC); 
 //KeyGenerator 生成aes算法密钥 
 secretKey = KeyGenerator.getInstance(KEY_ALGORITHM).generateKey(); 
 System.out.println("密钥的长度为:" + secretKey.getEncoded().length); 
   
 cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(getIV()));//使用加密模式初始化 密钥 
 byte[] encrypt = cipher.doFinal(str.getBytes()); //按单部分操作加密或解密数据,或者结束一个多部分操作。 
   
 System.out.println("method3-加密:" + Arrays.toString(encrypt)); 
 cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(getIV()));//使用解密模式初始化 密钥 
 byte[] decrypt = cipher.doFinal(encrypt); 
 System.out.println("method3-解密后:" + new String(decrypt)); 
   
 } 
  
 /** 
 * 使用AES 算法 加密,默认模式 AES/CBC/NoPadding 参见上面对于这种mode的数据限制 
 */
 static void method4(String str) throws Exception { 
 cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC_NoPadding); 
 //KeyGenerator 生成aes算法密钥 
 secretKey = KeyGenerator.getInstance(KEY_ALGORITHM).generateKey(); 
 System.out.println("密钥的长度为:" + secretKey.getEncoded().length); 
   
 cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(getIV()));//使用加密模式初始化 密钥 
 byte[] encrypt = cipher.doFinal(str.getBytes(), 0, str.length()); //按单部分操作加密或解密数据,或者结束一个多部分操作。 
   
 System.out.println("method4-加密:" + Arrays.toString(encrypt)); 
 cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(getIV()));//使用解密模式初始化 密钥 
 byte[] decrypt = cipher.doFinal(encrypt); 
   
 System.out.println("method4-解密后:" + new String(decrypt)); 
   
 } 
  
}

관련 기사를 공유하기 위한 AES 암호화 알고리즘의 Java 구현에 대한 더 간단한 예를 보려면 PHP 중국어 웹사이트에 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.