精华内容
下载资源
问答
  • AES加密算法java实现

    2019-07-23 18:18:38
    AES加密算法是密码学中的高级加密标准,该加密算法采用对称分组密码体制,密钥长度的最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。这种加密算法是美国联邦政府采用的区块加密标准,这个...

    转载自: https://blog.csdn.net/zyhlwzy/article/details/77948165

    AES加密算法是密码学中的高级加密标准,该加密算法采用对称分组密码体制,密钥长度的最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。这种加密算法是美国联邦政府采用的区块加密标准,这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。

    过多原理不做解释,可以参考(AES加密算法原理http://www.jiamisoft.com/blog/858-aesjiamisuanfa.html)

    java中的具体使用如下:

    public class SecurityAESUtils {
    private static Logger logger = LogManager.getLogger(SecurityAESUtils.class);

    private static final String ENCODEING = "UTF-8";
    private static final String ALGORITHM = "AES";//加密算法
    
    private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//算法/工作模式/填充方式 
    
    /**
     * 加密
     * @param plaintext 明文
     * @param secureKey 16位长度的密钥
     * @return
     */
    public static String encrypt(String plaintext, String secureKey) throws Exception{
        SecretKeySpec sks = getSecretKeySpec(secureKey);
        Cipher encryptCipher = getCipher(Cipher.ENCRYPT_MODE, sks);
        byte[] result = encryptCipher.doFinal(plaintext.getBytes(ENCODEING));
        return  Base64.encodeBase64String(result);
    }
    
    /**
     * 加密
     * @param bytes 
     * @param secureKey 16位长度的密钥
     * @return
     */
    public static String encryptBytes(byte[] bytes, String secureKey) throws Exception{
        SecretKeySpec sks = getSecretKeySpec(secureKey);
        Cipher encryptCipher = getCipher(Cipher.ENCRYPT_MODE, sks);
        byte[] result = encryptCipher.doFinal(bytes);
        return  Base64.encodeBase64String(result);
    }
    
    /**
     * 解密
     * @param ciphertext 密文
     * @return secureKey 16位长度的密钥
     * @throws Exception
     */
    public static String decrypt(String ciphertext, String secureKey) throws Exception {
        SecretKeySpec sks = getSecretKeySpec(secureKey);
        Cipher decryptCiphe = getCipher(Cipher.DECRYPT_MODE, sks);//initDecryptCipher(secureKey);
        byte[] result =  decryptCiphe.doFinal(Base64.decodeBase64(ciphertext));
        return new String(result, ENCODEING);
    }
    
    private static Cipher getCipher(int cipherMode, SecretKeySpec sks) throws Exception{
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(cipherMode, sks);
        return cipher;
    }
    
    private static SecretKeySpec getSecretKeySpec(String secureKey) throws Exception{
        if(secureKey == null || secureKey.trim().equals("") || secureKey.length() != 16){
            throw new Exception("密钥不能为空或密钥长度不对");
        }
        byte[] raw = secureKey.getBytes(ENCODEING);
        SecretKeySpec skeySpec = new SecretKeySpec(raw, ALGORITHM);
        return skeySpec;
    }
    
    /**
     * @Comment 加密不限制密码长度
     * @Author Ron
     * @Date 2017年9月12日 下午3:21:59
     * @return
     */
    public static String encryptNotLimit(String plaintext, String secureKey) throws Exception{
        SecretKeySpec sks = getSecretKeySpecByRandomSeed(secureKey);
        Cipher encryptCipher = getCipher(Cipher.ENCRYPT_MODE, sks);
        byte[] result = encryptCipher.doFinal(plaintext.getBytes(ENCODEING));
        return Hex.encodeHexString(result);
    }
    
    /**
     * @Comment 解密不限制密码长度
     * @Author Ron
     * @Date 2017年9月12日 下午3:22:30
     * @return
     */
    public static String decryptNotLimit(String ciphertext, String secureKey) throws Exception {
        SecretKeySpec sks = getSecretKeySpecByRandomSeed(secureKey);
        Cipher decryptCiphe = getCipher(Cipher.DECRYPT_MODE, sks);
        byte[] result =  decryptCiphe.doFinal(Hex.decodeHex(ciphertext.toCharArray()));
        return new String(result, ENCODEING);
    }
    
    /**
     * @Comment 构造私钥
     * @Author Ron
     * @Date 2017年9月12日 下午3:22:59
     * @return
     */
    private static SecretKeySpec getSecretKeySpecByRandomSeed(String secureKey){
        SecretKeySpec sks = null;
        try {
            KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);
            //安全随机数生成器 
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");//使用默认的SHA1PRNG算法
            secureRandom.setSeed(secureKey.getBytes(ENCODEING));
            kgen.init(128, secureRandom); 
            SecretKey secretKey = kgen.generateKey();
            byte[] secretKeyEncoded = secretKey.getEncoded();
            sks = new SecretKeySpec(secretKeyEncoded, ALGORITHM);
        } catch (Exception e) {
            logger.error("",e);
        }
        return sks;
    }
    
    public static void main(String[] args) throws Exception {
        String key = "ron.zheng@tfscha";
        String src = "我是Ron";
        String enString = encrypt(src,key);
        System.out.println("加密后的数据:"+enString);
        System.out.println("解密后的数据:"+decrypt(enString,key));
    
        //不限制密钥长度
        String nkey = "ron.zheng@tfschang.com";
        enString = encryptNotLimit(src, nkey);
        System.out.println("加密后的数据:"+enString);
        System.out.println("解密后的数据:"+decryptNotLimit(enString,nkey));
    }
    

    }

    展开全文
  • 北京交通大学密码学作业,第三次实验源码及实验报告,包括工程文件和测试用例
  • 算法AES 模式:ECB 密钥长度:128位 密钥:自己填(代码中带补位) 补码方式:PKCS5Padding/PKCS7Padding (两种方式结果一致) 加密结果编码方式:十六进制/base64(两种编码方式的代码都有,见注释) ...

     

    img

    算法:AES

    模式:ECB

    密钥长度:128位

    密钥:自己填(代码中带补位)

    补码方式:PKCS5Padding/PKCS7Padding (两种方式结果一致)

    加密结果编码方式:十六进制/base64(两种编码方式的代码都有,见注释)

     

    github地址:https://github.com/LucasXu01/aesutil

    展开全文
  • Java实现AES加密算法

    热门讨论 2011-03-02 17:07:15
    Java实现AES加密算法Java实现AES加密算法
  • AES加密算法JAVA实现

    2015-12-27 02:30:59
    AES加密算法JAVA实现(只有加密)
  • AES加密算法java源代码

    热门讨论 2011-08-29 00:30:37
    AES加密算法java实现源代码。只有一个java源文件,非常简单。
  • AES加密算法 Java与Python跨平台实现

    千次阅读 2018-12-13 18:10:12
    AES加密算法 Java与Python跨平台实现什么是AESJava实现Python的实现 什么是AES Note: 网上有很多实现代码但是鱼龙混杂,笔者摸索了半天,实现了AES加密文本跨平台的安全传输 这里以Python和Java为例,方案采用...

    AES加密算法 Java与Python跨平台实现

    什么是AES

    Note:

    1. 网上有很多实现代码但是鱼龙混杂,笔者摸索了半天,实现了AES加密文本跨平台的安全传输
    2. 这里以Python和Java为例,方案采用AES128+Base64.这里以Python和Java为例,方案采用AES128+Base64。

    AES的算法本身是跨平台的,只不过以下这些要素决定了跨平台不是那么简单:

    • 加密模式: ECB,CBC,CFB,OFB,CTR,XTS…
    • 密钥长度: 128, 256
    • iv向量(init vector): 需要与密钥同时设置
    • padding: NoPadding,ZeroPadding,PKCS5Padding,ISO10126Padding,ANSI X.923,SSL3Padding…
    • 密钥: 用于加解密的key
      参见: Github aes-cross

    Java的实现

    Note:

    1. Base64 需要第三方jar包 http://www.java2s.com/Code/Jar/a/Downloadaxis103jar.htm
    2. 注意padding与unpadding的方法
    import java.util.Arrays;
    import java.lang.Throwable;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    import org.apache.axis.encoding.Base64;
    
    public class aesEncryption {
        private static final String CYPHER_MODE = "AES/CBC/NoPadding";
    
        public static byte[] encrypt(byte[] key, byte[] initVector, byte[] value) {
            try {
                IvParameterSpec iv = new IvParameterSpec(initVector);
                SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    
                Cipher cipher = Cipher.getInstance(CYPHER_MODE);
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
                int blockSize = cipher.getBlockSize();
                byte[] plaintext = padding(value, blockSize);
                return cipher.doFinal(plaintext);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            return null;
        }
    
        public static byte[] decrypt(byte[] key, byte[] initVector, byte[] encrypted) {
            try {
                IvParameterSpec iv = new IvParameterSpec(initVector);
                SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    
                Cipher cipher = Cipher.getInstance(CYPHER_MODE);
                cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
    
                return unpadding(cipher.doFinal(encrypted));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            return null;
        }
    
        private static byte[] padding(byte[] value, int blockSize) {
            int plaintextLength = value.length;
            if (plaintextLength % blockSize != 0) {
                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
            }
            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(value, 0, plaintext, 0, value.length);
            return plaintext;
        }
    
        private static byte[] unpadding(byte[] bytes) {
            int i = bytes.length - 1;
            while (i >= 0 && bytes[i] == 0)
            {
                --i;
            }
    
            return Arrays.copyOf(bytes, i + 1);
        }
    
        public static void main(String[] args) {
            try {
                byte[] key = "keyskeyskeyskeys".getBytes();
                byte[] iv = "keyskeyskeyskeys".getBytes();
                byte[] content = "123".getBytes("utf-8");
                byte[] cyphertext = encrypt(key, iv, content);
                String b64 = Base64.encode(cyphertext);
                System.out.println(b64);
                byte[] de_b64 = decrypt(key, iv, Base64.decode(b64));
                String plaintext = new String(de_b64);
                System.out.println(plaintext);
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
    }
    

    Python的实现

    Note:

    1. key 和 iv 值要与之前的Java代码里分别
    2. 注意padding与unpadding的方法
    from Crypto.Cipher import AES
    import base64
    
    
    class AESEncrypt:
        def __init__(self, key, iv):
            self.key = key
            self.iv = iv
            self.mode = AES.MODE_CBC
    
        def encrypt(self, text):
            cryptor = AES.new(self.key, self.mode, self.key)
            length = AES.block_size
            text_pad = self.padding(length, text)
            ciphertext = cryptor.encrypt(text_pad)
            cryptedStr = str(base64.b64encode(ciphertext), encoding='utf-8')
            return cryptedStr
    
        def padding(self, length, text):
            count = len(text.encode('utf-8'))
            if count % length != 0:
                add = length - (count % length)
            else:
                add = 0
            text1 = text + ('\0' * add)
            return text1
    
        def decrypt(self, text):
            base_text = base64.b64decode(text)
            cryptor = AES.new(self.key, self.mode, self.key)
            plain_text = cryptor.decrypt(base_text)
            ne = plain_text.decode('utf-8').rstrip('\0')
            return ne
    
    
    if __name__ == '__main__':
        aes_encrypt = AESEncrypt(key='keyskeyskeyskeys', iv="keyskeyskeyskeys")  # 初始化key和IV
        text = '123'
        sign_data = aes_encrypt.encrypt(text)
        print(sign_data)
        data = aes_encrypt.decrypt(sign_data)
        print(data)
    

    结果

    明文:123
    密文:nUY/Ft988QAYJYbKh2pxyw==

    展开全文
  • AES_Java 使用Java实现AES加密算法的完整过程
  • 主要介绍了java实现AES加密算法,结合完整实例形式分析了AES加密类的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • aes加密算法java代码实现

    千次阅读 2015-02-13 18:08:39
    public class Aes { public enum KeySize{ Bits128(4,10),Bits192(6,12),Bits256(8,14); /**以字为单位的种子密钥长度,16bytes=1word=128bits*/ private int nk; /**轮密钥的次数*/ private int

    这周学习下aes加密算法,网上一搜发现没java代码版的,查阅了aes算法原理及几篇文章,自己照着原理把java版代码做出来了。本文仅呈现算法的java代码实现,关于算法原理可查阅最底部的参考文献。

    Aes加密及解密流程图



    package com.vk.aesdemo;
    
    public class Aes {
    	
    	public enum KeySize{
    		Bits128(4,10),Bits192(6,12),Bits256(8,14);
    		/**以字为单位的种子密钥长度,16bytes=1word=128bits*/
    		private int nk;
    		/**轮密钥的次数*/
    		private int nr;
    		private KeySize(int nk,int nr){
    			this.nk = nk;
    			this.nr = nr;
    		}
    	}
    
    	private char[][] rcon ={
    			{0x00,0x00,0x00,0x00},
    			{0x01,0x00,0x00,0x00},
    			{0x02,0x00,0x00,0x00},
    			{0x04,0x00,0x00,0x00},
    			{0x08,0x00,0x00,0x00},
    			{0x10,0x00,0x00,0x00},
    			{0x20,0x00,0x00,0x00},
    			{0x40,0x00,0x00,0x00},
    			{0x80,0x00,0x00,0x00},
    			{0x1b,0x00,0x00,0x00},
    			{0x36,0x00,0x00,0x00}
    		};
    		
    	char sbox[] = 
    		{
    		   0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
    		   0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
    		   0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
    		   0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
    		   0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
    		   0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
    		   0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
    		   0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
    		   0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
    		   0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
    		   0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
    		   0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
    		   0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
    		   0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
    		   0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
    		   0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
    		};
    	
    	char isbox[] = 
    		{
    		   0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    		   0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    		   0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    		   0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    		   0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    		   0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    		   0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    		   0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    		   0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    		   0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    		   0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    		   0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    		   0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    		   0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    		   0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    		   0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
    		};
    	
    	/**以字为单位的种子密钥长度,16bytes=1word=128bits*/
    	private int nk;
    	/**轮密钥的次数*/
    	private int nr;
    	/**以字节为单位的明文长度,固定值16字节*/
    	private static final int nb = 16;
    	/**密钥轮值表数组*/
    	private byte[] keys;
    	private byte[] data;
    	
    	public Aes(KeySize keySize,byte[] keys){
    		setNkNr(keySize);
    		keyExpansion(keys);
    	}
    	
    	private void setNkNr(KeySize keySize){
    		nk = keySize.nk;
    		nr = keySize.nr;
    	}
    	
    	/**
    	 * 密钥扩展,创建密钥调度表
    	 * @param keys 种子密钥
    	 */
    	private void keyExpansion(byte[] inkeys){
    		if(inkeys == null || 
    				(inkeys.length != 16 && inkeys.length != 24 && inkeys.length != 32))
    			throw new IllegalArgumentException("keys length out of range{16,24,32}");
    		keys = new byte[nb*(nr+1)];//轮密钥次数nr,再加上轮值之前的1次addRoundKey预处理
    		System.arraycopy(inkeys, 0, keys, 0, inkeys.length);
    		int totalRow = nb*(nr+1)/4;
    		byte[] tmp = new byte[4];
    		int index = 0;
    		for(int row = nk;row < totalRow;row++){
    			//循环一次处理一个round的密钥, 一行4字节
    			index = 4*(row - 1);
    			tmp[0] = keys[index];
    			tmp[1] = keys[index+1];
    			tmp[2] = keys[index+2];
    			tmp[3] = keys[index+3];
    			if(row%nk == 0)
    				tmp = xorRcon(row, subWord(rotWord(tmp)));
    			else if(nk == 8 && (row % nk == 4)){
    				tmp = subWord(tmp);
    			}
    			
    			keys[row*4] = (byte) (keys[(row-nk)*4] ^ tmp[0]);
    			keys[row*4+1] = (byte) (keys[(row-nk)*4+1] ^ tmp[1]);
    			keys[row*4+2] = (byte) (keys[(row-nk)*4+2] ^ tmp[2]);
    			keys[row*4+3] = (byte) (keys[(row-nk)*4+3] ^ tmp[3]);
    		}
    		
    	}
    	
    	private void addRoundKey(int row){
    		for(int i = 0;i < 4;i++){
    			//每轮密钥调度,16字节一组
    			//循环一次处理一个round的密钥, 一行4字节,4次共16字节
    //			data[i*4] ^= keys[ row*16+i];
    //			data[i*4+1] ^= keys[ row*16+1*4+i];
    //			data[i*4+2] ^= keys[ row*16+2*4+i];
    //			data[i*4+3] ^= keys[ row*16+3*4+i];
    			
    			data[i*4] ^= keys[ row*16+4*i];
    			data[i*4+1] ^= keys[ row*16+4*i+1];
    			data[i*4+2] ^= keys[ row*16+4*i+2];
    			data[i*4+3] ^= keys[ row*16+4*i+3];
    		}
    	}
    	
    	/**
    	 * 进行s-box非线性变换
    	 */
    	private void subBytes(){
    		for(int i = 0;i<16;i++)
    			data[i] = (byte) sbox[data[i]&0xff];
    	}
    	
    	/**
    	 * 进行is-box非线性变换
    	 */
    	private void invSubBytes(){
    		for(int i = 0;i<16;i++)
    			data[i] = (byte) isbox[data[i]&0xff];
    	}
    	
    	
    	/**
    	 * 4x4矩阵(x,y)数组,每行循环左移x个字节
    	 */
    	private void shiftRows(){
    		byte[] tmp = new byte[4];
    		int n;
    		for(int i = 0;i<4;i++){
    			n = i*4;
    			tmp[0] = data[n];
    			tmp[1] = data[n+1];
    			tmp[2] = data[n+2];
    			tmp[3] = data[n+3];
    			
    			data[n] = tmp[i%4];
    			data[n+1] = tmp[(1+i)%4];
    			data[n+2] = tmp[(2+i)%4];
    			data[n+3] = tmp[(3+i)%4];
    		}	
    	}
    	
    	/**
    	 * 4x4矩阵(x,y)数组,每行循环右移x个字节
    	 */
    	private void invShiftRows(){
    		byte[] tmp = new byte[4];
    		int n;
    		for(int i = 0;i<4;i++){
    			n = i*4;
    			tmp[0] = data[n];
    			tmp[1] = data[n+1];
    			tmp[2] = data[n+2];
    			tmp[3] = data[n+3];
    			
    			data[n+i%4] = tmp[0];
    			data[n+(1+i)%4] = tmp[1];
    			data[n+(2+i)%4] = tmp[2];
    			data[n+(3+i)%4] = tmp[3];
    		}	
    	}
    	
    	/**
    	 * 按列混合
    	 */
    	private void mixColumns(){
    		byte[] tmp = new byte[4];
     		for(int i = 0;i< 4;i++){
    			tmp[0] = data[i];
    			tmp[1] = data[i+4];
    			tmp[2] = data[i+8];
    			tmp[3] = data[i+12];
    			
    			data[i] = (byte) (gfmulBy02(tmp[0])^gfmulBy03(tmp[1])^gfmulBy01(tmp[2])^gfmulBy01(tmp[3]));
    			data[i+4] = (byte) (gfmulBy01(tmp[0])^gfmulBy02(tmp[1])^gfmulBy03(tmp[2])^gfmulBy01(tmp[3]));
    			data[i+8] = (byte) (gfmulBy01(tmp[0])^gfmulBy01(tmp[1])^gfmulBy02(tmp[2])^gfmulBy03(tmp[3]));
    			data[i+12] = (byte) (gfmulBy03(tmp[0])^gfmulBy01(tmp[1])^gfmulBy01(tmp[2])^gfmulBy02(tmp[3]));
    			
    		}
    			
    	}
    	
    	/**
    	 * 按列逆混合
    	 */
    	private void invMixColumns(){
    		byte[] tmp = new byte[4];
    		for(int i = 0;i< 4;i++){
    			tmp[0] = data[i];
    			tmp[1] = data[i+4];
    			tmp[2] = data[i+8];
    			tmp[3] = data[i+12];
    			
    			data[i+0] = (byte) (gfmulBy0e(tmp[0]) ^ gfmulBy0b(tmp[1]) ^ gfmulBy0d(tmp[2]) ^ gfmulBy09(tmp[3]));
    			data[i+4] = (byte) (gfmulBy09(tmp[0]) ^ gfmulBy0e(tmp[1]) ^ gfmulBy0b(tmp[2]) ^ gfmulBy0d(tmp[3]));
    			data[i+8] = (byte) (gfmulBy0d(tmp[0]) ^ gfmulBy09(tmp[1]) ^ gfmulBy0e(tmp[2]) ^ gfmulBy0b(tmp[3]));
    			data[i+12] = (byte) (gfmulBy0b(tmp[0]) ^ gfmulBy0d(tmp[1]) ^ gfmulBy09(tmp[2]) ^ gfmulBy0e(tmp[3]));
    			
    		}
    	}
    	
    	private byte gfmulBy01(byte value){
    		return value;
    	}
    	
    	private byte gfmulBy02(byte value){
    		if((int)value > 0x80)
    			value = (byte)((value<<1)^0x1b);
    		else
    			value =  (byte)(value<<1);
    		return value;
    	}
    	
    	private byte gfmulBy03(byte value){
    		return (byte) (gfmulBy01(value)^gfmulBy02(value));
    	}
    	
    	private byte gfmulBy09(byte value){
    		return (byte) (gfmulBy01(value)^gfmulBy02(gfmulBy02(gfmulBy02(value))));
    	}
    	private byte gfmulBy0b(byte value){
    		return (byte) (gfmulBy01(value)^gfmulBy02(value)^gfmulBy02(gfmulBy02(gfmulBy02(value))));
    	}
    	
    	private byte gfmulBy0d(byte value){
    		return (byte) (gfmulBy01(value)^gfmulBy02(gfmulBy02(value))^gfmulBy02(gfmulBy02(gfmulBy02(value))));
    	}
    	
    	private byte gfmulBy0e(byte value){
    		return (byte) (gfmulBy02(value)^gfmulBy02(gfmulBy02(value))^gfmulBy02(gfmulBy02(gfmulBy02(value))));
    	}
    
    	private byte[] rotWord(byte[] word){
    		return new byte[]{word[1],word[2],word[3],word[0]}; 
    	}
    	
    	private byte[] subWord(byte[] word){
    		return new byte[]{(byte) sbox[word[0]&0xff],(byte) sbox[word[1]&0xff],
    				(byte) sbox[word[2]&0xff],(byte) sbox[word[3]&0xff]};
    	}
    	
    	private byte[] xorRcon(int row,byte[] word){
    		byte[] ret = new byte[4];
    		ret[0] = (byte) (word[0] ^ rcon[row/nk][0]);
    		ret[1] = (byte) (word[1] ^ rcon[row/nk][1]);
    		ret[2] = (byte) (word[2] ^ rcon[row/nk][2]);
    		ret[3] = (byte) (word[3] ^ rcon[row/nk][3]);
    		return ret;
    	}
    	
    	/**
    	 * 加密
    	 * @param plainText
    	 * @return
    	 */
    	public byte[] cipher(byte[] plainText){
    		if(plainText == null || plainText.length == 0)
    			throw new IllegalArgumentException("plainText can not be null");
    		data = new byte[16];
    		System.arraycopy(plainText, 0, data, 0, plainText.length);
    		
    		addRoundKey(0);//预处理一次
    		for(int row = 1;row < nr;row++){
    			subBytes();
    			
    			shiftRows();
    			
    			mixColumns();
    			
    			addRoundKey(row);
    		}
    		//最后一轮不需要执行mixColumns
    		subBytes();
    		shiftRows();
    		addRoundKey(nr);
    		return data;
    	}
    	
    	/**
    	 * 解密
    	 * @param cipherText
    	 * @return 
    	 */
    	public byte[] invCipher(byte[] cipherText){
    		if(cipherText == null || cipherText.length == 0)
    			throw new IllegalArgumentException("cipherText can not be null");
    		data = new byte[16];
    		System.arraycopy(cipherText, 0, data, 0, cipherText.length);
    		
    		addRoundKey(nr);//预处理一次
    		for(int row = nr-1;row > 0;row--){
    			invShiftRows();
    			invSubBytes();
    			addRoundKey(row);
    			invMixColumns();
    		}
    		//最后一轮不需要执行mixColumns
    		
    		invShiftRows();
    		invSubBytes();
    		addRoundKey(0);
    //		print();
    		return data;
    	}
    	
    	public static void main(String[] args){
    		byte[] keys = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
    				0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 };
    		Aes aes = new Aes(KeySize.Bits192, keys);
    		//--------加密-------------------------
    		String plainText = "1234abcd";
    		byte[] cipherText = aes.cipher(plainText.getBytes());
    		
    		System.out.println("plainText: "+plainText);
    		StringBuffer m = new StringBuffer();
    		for(int i = 0;i< 16;i++){
    			if((cipherText[i]&0xff) > 0x0f)
    				m.append(String.format("%x", cipherText[i]));
    			else
    				m.append(String.format("0%x", cipherText[i]));
    			m.append(" ");
    		}
    		System.out.println("cipherText:"+m);
    		
    		//--------解密-------------------------
    		byte[] ret = aes.invCipher(cipherText);
    		String val = new String(ret);
    		System.out.println("invCipher cipherText : "+val);
    		
    	}
    	
    }
    

    参考文献:

    http://zh.wikipedia.org/wiki/%E9%AB%98%E7%BA%A7%E5%8A%A0%E5%AF%86%E6%A0%87%E5%87%86
    http://www.2cto.com/Article/201112/113465.html
    http://mingcn.cnblogs.com/archive/2010/10/31/aes_c.html



    
    
    展开全文
  • AES加密算法原理 1. S-P结构加密 AES加密算法是2001年由美国提出的互联网加密算法,从密码学的角度来讲,AES是典型的S-P结构加密。什么是S-P结构加密呢,手残博主画了一张图帮助大家理解: 从这张图中可以看到,M...
  • AES加密算法JAVA实现示例

    千次阅读 2016-04-26 14:01:42
    最近项目上需要用到数据加密存储,查询资料后发现目前AES加密算法安全度非常高,具体原理可自行百度。但经网上搜到的JAVA实现示例运行都有各种问题,耗时一下午,终于调试运行成功,闲话少说,直接上代码。
  • AES加密算法java实现

    热门讨论 2015-01-15 16:32:38
    AES高级加密标准,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种...本软件是用java语言开发,实现AES算法对文件的加密和解密,并在界面上加了进度条,来提示用户加密解密的进度。如果不足之处,欢迎留言。
  • JAVA AES 加密算法

    2020-08-29 17:17:53
    JAVA AES 加密算法 javax.crypto.Cipher AES/ECB/PKCS5Padding
  • JAVA AES加密算法实现代码

    千次阅读 2015-07-28 14:20:29
    JAVA AES加密算法实现代码
  • AES加密算法的理解及Java实现

    千次阅读 2017-06-22 21:02:28
    AES加密算法的理解及Java实现
  • 主要介绍了Java实现AES加密算法的简单示例分享,AES算法是基于对密码值的置换和替代,需要的朋友可以参考下
  • AES算法加密java实现

    千次阅读 2014-08-30 13:24:52
    AES算法加密java实现 import java.security.Key; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec;
  • AES加密AES加密AES加密AES加密AES加密AES加密
  • 安全架构-加密算法-AES加密Java实现

    千次阅读 2020-12-21 22:44:33
    加密算法-AES加密Java实现 AES  高级数据加密标准(Advanced Encryption Standard),简称AES,由美国政府于1997年开始公开征集的新的数据加密标准算法。经过三轮筛选,美国政府最终于2000年10月2日正式宣布选中...
  • AES加密算法实现

    2018-12-20 16:35:06
    高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法。对称加密算法也就是加密和解密需要使用相同的密钥。 应用场景:接口之间的数据传输 需要用到的包:commons-codec-1.5.jar(其他版本的也...
  • /** * 生成AES密钥 * * @return Keys.Aes * @throws NoSuchAlgorithmException */ public static Keys.... Keys.Aes aes = new Keys().new Aes(Tools.encodeToString(secretKey.getEncoded())); return aes; }
  • 使用JAVA实现AES算法,代码通俗易懂,方便初学者对AES进行研究与学习
  • AES加密解密算法Java实现

    千次阅读 2017-03-16 15:01:48
    AES加密算法是密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。 AES...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,100
精华内容 7,240
关键字:

aes加密算法java实现

java 订阅