大家都知道AES加密解密又称为对称加密解密,详细的介绍在百度百科以及其他大佬的博客上有很多讲解,这里我就不在重复基本知识了,只做js和java两端加密解密操作对比。(试用范围:WEB开发登陆加密解密操作、APP重要信息上传、APP蓝牙通信等)。

一、java和js使用AES-ECB加密解密对比(最后的js库包含有aes所有的加解密  )

的充方式 PKCS5Padding,有一位大佬已经写了的,就直接分享大佬连接吧,连接。

填充方式 nopadding,参照大佬的思路,我的代码

java部分:

package LinkpowerLock.AES.ECB;

import java.math.BigInteger;
import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;

public class ECBTest {
	//密钥 (需要前端和后端保持一致)
    private static final String KEY = "abcdefgabcdefg12";  
    //算法
    private static final String ALGORITHMSTR = "AES/ECB/NoPadding";
    
      
      
    /** 
     * aes加密 
     * @param content 
     * @return 
     * @throws Exception 
     */  
    public static String aesEncrypt(String content) {  
        try {
            return aesEncrypt(content, KEY);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }  
    }  
  
    /** 
     * 将byte[]转为各种进制的字符串 
     * @param bytes byte[] 
     * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制 
     * @return 转换后的字符串 
     */  
    public static String binary(byte[] bytes, int radix){  
        return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数  
    }  
  
    /** 
     * base 64 encode 
     * @param bytes 待编码的byte[] 
     * @return 编码后的base 64 code 
     */  
    public static String base64Encode(byte[] bytes){  
        return Base64.encodeBase64String(bytes);  
    }  
  
     
  
      
    /** 
     * AES加密 
     * @param content 待加密的内容 
     * @param encryptKey 加密密钥 
     * @return 加密后的byte[] 
     * @throws Exception 
     */  
    public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {  
        /*KeyGenerator kgen = KeyGenerator.getInstance("AES");  
        kgen.init(128);  
        Cipher cipher = Cipher.getInstance(ALGORITHMSTR);  
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));  
        return cipher.doFinal(content.getBytes("utf-8"));  */
    	
    	Key key = new SecretKeySpec(encryptKey.getBytes(), "AES");
		Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
		cipher.init(Cipher.ENCRYPT_MODE, key);
		return cipher.doFinal(content.getBytes());
    }  
  
  
    /** 
     * AES加密为base 64 code 
     * @param content 待加密的内容 
     * @param encryptKey 加密密钥 
     * @return 加密后的base 64 code 
     * @throws Exception 
     */  
    public static String aesEncrypt(String content, String encryptKey) throws Exception {  
        ///return base64Encode(aesEncryptToBytes(content, encryptKey));  
    	return parseByte2HexStr(aesEncryptToBytes(content, encryptKey));  
    }  
    
    public static String parseByte2HexStr(byte buf[]) {  
        StringBuffer sb = new StringBuffer();  
        for (int i = 0; i < buf.length; i++) {  
            String hex = Integer.toHexString(buf[i] & 0xFF);  
            if (hex.length() == 1) {  
                hex = '0' + hex;  
            }  
            sb.append(hex.toUpperCase());  
        }  
        return sb.toString();  
    }  
  
    
    /**
     * 测试
     */
    public static void main(String[] args) throws Exception {  
        String content = "1111111111111111";  
        String keys = "1111111111111111";
        System.out.println("加密前:" + content);  
        System.out.println("加密密钥和解密密钥:" + keys);  
        String encrypt = aesEncrypt(content, keys);  
        System.out.println("加密后:" + encrypt);
}

java部分执行后的打印结果:

加密前:1111111111111111
加密密钥和解密密钥:1111111111111111
加密后:AD0110483D0559D12E8CB97203E6C908

java-AES-ECB代码2:

import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 * aes加密解密操作
 * @author 76519
 *
 */
public class AesSafeUtil {
	/**
	 * 算法类型
	 */
	static final String algorithmstr = "AES/ECB/NoPadding";
	/**
	 * 加密操作
	 * @param context 传入明文的byte[]
	 * @param keyBytes 传入加解密的key的byte[]
	 * @return 加密后的结果
	 */
	public static byte[] encrypt(byte[] context,byte[] keyBytes) throws Exception{
		Key key = new SecretKeySpec(keyBytes, "AES");
		Cipher cipher = Cipher.getInstance(algorithmstr);
		cipher.init(Cipher.ENCRYPT_MODE, key);
		return cipher.doFinal(context);
	}
	
	/**
	 * 
	 * @param context 密文
	 * @param keyBytes 加解密的key
	 * @return 解密后的结果
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] context,byte[] keyBytes){
		SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); 
		Cipher cipher;
		try {
			cipher = Cipher.getInstance(algorithmstr);
			cipher.init(Cipher.DECRYPT_MODE, key);
			return cipher.doFinal(context);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/** 
     * @param buf 
     * @return 
     */  
    public static String parseByte2HexStr(byte buf[]) {  
        StringBuffer sb = new StringBuffer();  
        for (int i = 0; i < buf.length; i++) {  
            String hex = Integer.toHexString(buf[i] & 0xFF);  
            if (hex.length() == 1) {  
                hex = '0' + hex;  
            }  
            sb.append(hex.toUpperCase());  
        }  
        return sb.toString();  
    }  
	
	/** 
     * @param hexStr 
     * @return 
     */  
    public static byte[] parseHexStr2Byte(String hexStr) {  
        if (hexStr.length() < 1)  
            return null;   
        byte[] result = new byte[hexStr.length() / 2];  
        for (int i = 0; i < hexStr.length() / 2; i++) {  
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);  
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),  
                    16);  
            result[i] = (byte) (high * 16 + low);  
        }  
        return result;  
    }  
    
    public static void main(String[] args) throws Exception {
		System.out.println(parseByte2HexStr(encrypt("1111111111111111".getBytes(),"1111111111111111".getBytes())));
	}
}

前端js部分的加密解密:

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>

	<body>
	</body>
	<script src="aes.js" type="text/javascript" charset="utf-8"></script>
	<script src="../../js/pad-nopadding.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		window.onload = function() {
			console.log("66666");
			console.log(encrypt1("1111111111111111"))
			console.log("---->"+encrypt1("1111111111111111").ciphertext);//真实加密后的结果
			console.log("type--->"+typeof(encrypt1("1111111111111111").ciphertext)) //object
			console.log(CryptoJS.enc.Utf8.parse(encrypt1("1111111111111111")))
			//console.log("解密-->"+decrypt(encrypt1("1111111111111111")))
		}

		/**
		 * 加密
		 * @param word
		 * @returns {*}
		 */
		function encrypt1(word) {
			var key = CryptoJS.enc.Utf8.parse(1111111111111111);
			console.log("###***##-->"+key)
			console.log("key-type "+ typeof(key))
			var srcs = CryptoJS.enc.Utf8.parse(word);
			
			/*var srcs = CryptoJS.enc.Hex.parse(word); 
			console.log("###   ##-->"+srcs)
			var key = CryptoJS.enc.Hex.parse(1111111111111111);*/
			console.log("###***##-->"+key)
			var encrypted = CryptoJS.AES.encrypt(srcs, key, {
				mode: CryptoJS.mode.ECB,
				padding: CryptoJS.pad.NoPadding
			});
			return encrypted;
		}
		
		function strToHexCharCode(str) {  
			if(str === "")     return "";  
			var hexCharCode = [];  
			hexCharCode.push("0x");  
			for(var i = 0; i < str.length; i++) {    
				hexCharCode.push((str.charCodeAt(i)).toString(16));  
			}
			return hexCharCode.join("");
		}

		/**
		 * 解密
		 * @param word
		 * @returns {*}
		 */
		function decrypt(word) {
			var key = CryptoJS.enc.Utf8.parse("1111111111111111");
			var decrypt = CryptoJS.AES.decrypt(word, key, {
				mode: CryptoJS.mode.ECB,
				padding: CryptoJS.pad.NoPadding
			});
			return CryptoJS.enc.Utf8.stringify(decrypt).toString();
		}
	</script>

</html>

运行结果:

[Web浏览器] "66666"	/wanwan/html/ecb/aes-ecb.html (15)
[Web浏览器] "###***##-->31313131313131313131313131313131"	/wanwan/html/ecb/aes-ecb.html (30)
[Web浏览器] "key-type object"	/wanwan/html/ecb/aes-ecb.html (31)
[Web浏览器] "###***##-->31313131313131313131313131313131"	/wanwan/html/ecb/aes-ecb.html (37)
[Web浏览器] "rQEQSD0FWdEujLlyA+bJCA=="	/wanwan/html/ecb/aes-ecb.html (16)
[Web浏览器] "###***##-->31313131313131313131313131313131"	/wanwan/html/ecb/aes-ecb.html (30)
[Web浏览器] "key-type object"	/wanwan/html/ecb/aes-ecb.html (31)
[Web浏览器] "###***##-->31313131313131313131313131313131"	/wanwan/html/ecb/aes-ecb.html (37)
[Web浏览器] "---->ad0110483d0559d12e8cb97203e6c908"	/wanwan/html/ecb/aes-ecb.html (17)
[Web浏览器] "###***##-->31313131313131313131313131313131"	/wanwan/html/ecb/aes-ecb.html (30)
[Web浏览器] "key-type object"	/wanwan/html/ecb/aes-ecb.html (31)
[Web浏览器] "###***##-->31313131313131313131313131313131"	/wanwan/html/ecb/aes-ecb.html (37)
[Web浏览器] "type--->object"	/wanwan/html/ecb/aes-ecb.html (18)
[Web浏览器] "###***##-->31313131313131313131313131313131"	/wanwan/html/ecb/aes-ecb.html (30)
[Web浏览器] "key-type object"	/wanwan/html/ecb/aes-ecb.html (31)
[Web浏览器] "###***##-->31313131313131313131313131313131"	/wanwan/html/ecb/aes-ecb.html (37)
[Web浏览器] "7251455153443046576445756a4c6c79412b624a43413d3d"	/wanwan/html/ecb/aes-ecb.html (19)

这里面用到了两个js库文件

aes.js库文件

!function(t,n){"object"==typeof exports?module.exports=exports=n():"function"==typeof define&&define.amd?define([],n):t.CryptoJS=n()}(this,function(){var t=t||function(t,n){var i=Object.create||function(){function t(){}return function(n){var i;return t.prototype=n,i=new t,t.prototype=null,i}}(),e={},r=e.lib={},o=r.Base=function(){return{extend:function(t){var n=i(this);return t&&n.mixIn(t),n.hasOwnProperty("init")&&this.init!==n.init||(n.init=function(){n.$super.init.apply(this,arguments)}),n.init.prototype=n,n.$super=this,n},create:function(){var t=this.extend();return t.init.apply(t,arguments),t},init:function(){},mixIn:function(t){for(var n in t)t.hasOwnProperty(n)&&(this[n]=t[n]);t.hasOwnProperty("toString")&&(this.toString=t.toString)},clone:function(){return this.init.prototype.extend(this)}}}(),s=r.WordArray=o.extend({init:function(t,i){t=this.words=t||[],i!=n?this.sigBytes=i:this.sigBytes=4*t.length},toString:function(t){return(t||c).stringify(this)},concat:function(t){var n=this.words,i=t.words,e=this.sigBytes,r=t.sigBytes;if(this.clamp(),e%4)for(var o=0;o<r;o++){var s=i[o>>>2]>>>24-o%4*8&255;n[e+o>>>2]|=s<<24-(e+o)%4*8}else for(var o=0;o<r;o+=4)n[e+o>>>2]=i[o>>>2];return this.sigBytes+=r,this},clamp:function(){var n=this.words,i=this.sigBytes;n[i>>>2]&=4294967295<<32-i%4*8,n.length=t.ceil(i/4)},clone:function(){var t=o.clone.call(this);return t.words=this.words.slice(0),t},random:function(n){for(var i,e=[],r=function(n){var n=n,i=987654321,e=4294967295;return function(){i=36969*(65535&i)+(i>>16)&e,n=18e3*(65535&n)+(n>>16)&e;var r=(i<<16)+n&e;return r/=4294967296,r+=.5,r*(t.random()>.5?1:-1)}},o=0;o<n;o+=4){var a=r(4294967296*(i||t.random()));i=987654071*a(),e.push(4294967296*a()|0)}return new s.init(e,n)}}),a=e.enc={},c=a.Hex={stringify:function(t){for(var n=t.words,i=t.sigBytes,e=[],r=0;r<i;r++){var o=n[r>>>2]>>>24-r%4*8&255;e.push((o>>>4).toString(16)),e.push((15&o).toString(16))}return e.join("")},parse:function(t){for(var n=t.length,i=[],e=0;e<n;e+=2)i[e>>>3]|=parseInt(t.substr(e,2),16)<<24-e%8*4;return new s.init(i,n/2)}},u=a.Latin1={stringify:function(t){for(var n=t.words,i=t.sigBytes,e=[],r=0;r<i;r++){var o=n[r>>>2]>>>24-r%4*8&255;e.push(String.fromCharCode(o))}return e.join("")},parse:function(t){for(var n=t.length,i=[],e=0;e<n;e++)i[e>>>2]|=(255&t.charCodeAt(e))<<24-e%4*8;return new s.init(i,n)}},f=a.Utf8={stringify:function(t){try{return decodeURIComponent(escape(u.stringify(t)))}catch(t){throw new Error("Malformed UTF-8 data")}},parse:function(t){return u.parse(unescape(encodeURIComponent(t)))}},h=r.BufferedBlockAlgorithm=o.extend({reset:function(){this._data=new s.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=f.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(n){var i=this._data,e=i.words,r=i.sigBytes,o=this.blockSize,a=4*o,c=r/a;c=n?t.ceil(c):t.max((0|c)-this._minBufferSize,0);var u=c*o,f=t.min(4*u,r);if(u){for(var h=0;h<u;h+=o)this._doProcessBlock(e,h);var p=e.splice(0,u);i.sigBytes-=f}return new s.init(p,f)},clone:function(){var t=o.clone.call(this);return t._data=this._data.clone(),t},_minBufferSize:0}),p=(r.Hasher=h.extend({cfg:o.extend(),init:function(t){this.cfg=this.cfg.extend(t),this.reset()},reset:function(){h.reset.call(this),this._doReset()},update:function(t){return this._append(t),this._process(),this},finalize:function(t){t&&this._append(t);var n=this._doFinalize();return n},blockSize:16,_createHelper:function(t){return function(n,i){return new t.init(i).finalize(n)}},_createHmacHelper:function(t){return function(n,i){return new p.HMAC.init(t,i).finalize(n)}}}),e.algo={});return e}(Math);return t});
//# sourceMappingURL=core.min.js.map
!function(e,t,i){"object"==typeof exports?module.exports=exports=t(require("./core.min"),require("./sha1.min"),require("./hmac.min")):"function"==typeof define&&define.amd?define(["./core.min","./sha1.min","./hmac.min"],t):t(e.CryptoJS)}(this,function(e){return function(){var t=e,i=t.lib,r=i.Base,n=i.WordArray,o=t.algo,a=o.MD5,c=o.EvpKDF=r.extend({cfg:r.extend({keySize:4,hasher:a,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var i=this.cfg,r=i.hasher.create(),o=n.create(),a=o.words,c=i.keySize,f=i.iterations;a.length<c;){s&&r.update(s);var s=r.update(e).finalize(t);r.reset();for(var u=1;u<f;u++)s=r.finalize(s),r.reset();o.concat(s)}return o.sigBytes=4*c,o}});t.EvpKDF=function(e,t,i){return c.create(i).compute(e,t)}}(),e.EvpKDF});
//# sourceMappingURL=evpkdf.min.js.map
!function(r,e){"object"==typeof exports?module.exports=exports=e(require("./core.min")):"function"==typeof define&&define.amd?define(["./core.min"],e):e(r.CryptoJS)}(this,function(r){return function(){function e(r,e,t){for(var n=[],i=0,o=0;o<e;o++)if(o%4){var f=t[r.charCodeAt(o-1)]<<o%4*2,c=t[r.charCodeAt(o)]>>>6-o%4*2;n[i>>>2]|=(f|c)<<24-i%4*8,i++}return a.create(n,i)}var t=r,n=t.lib,a=n.WordArray,i=t.enc;i.Base64={stringify:function(r){var e=r.words,t=r.sigBytes,n=this._map;r.clamp();for(var a=[],i=0;i<t;i+=3)for(var o=e[i>>>2]>>>24-i%4*8&255,f=e[i+1>>>2]>>>24-(i+1)%4*8&255,c=e[i+2>>>2]>>>24-(i+2)%4*8&255,s=o<<16|f<<8|c,h=0;h<4&&i+.75*h<t;h++)a.push(n.charAt(s>>>6*(3-h)&63));var p=n.charAt(64);if(p)for(;a.length%4;)a.push(p);return a.join("")},parse:function(r){var t=r.length,n=this._map,a=this._reverseMap;if(!a){a=this._reverseMap=[];for(var i=0;i<n.length;i++)a[n.charCodeAt(i)]=i}var o=n.charAt(64);if(o){var f=r.indexOf(o);f!==-1&&(t=f)}return e(r,t,a)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}}(),r.enc.Base64});
//# sourceMappingURL=enc-base64.min.js.map
!function(e,t,r){"object"==typeof exports?module.exports=exports=t(require("./core.min"),require("./evpkdf.min")):"function"==typeof define&&define.amd?define(["./core.min","./evpkdf.min"],t):t(e.CryptoJS)}(this,function(e){e.lib.Cipher||function(t){var r=e,i=r.lib,n=i.Base,c=i.WordArray,o=i.BufferedBlockAlgorithm,s=r.enc,a=(s.Utf8,s.Base64),f=r.algo,p=f.EvpKDF,d=i.Cipher=o.extend({cfg:n.extend(),createEncryptor:function(e,t){return this.create(this._ENC_XFORM_MODE,e,t)},createDecryptor:function(e,t){return this.create(this._DEC_XFORM_MODE,e,t)},init:function(e,t,r){this.cfg=this.cfg.extend(r),this._xformMode=e,this._key=t,this.reset()},reset:function(){o.reset.call(this),this._doReset()},process:function(e){return this._append(e),this._process()},finalize:function(e){e&&this._append(e);var t=this._doFinalize();return t},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(){function e(e){return"string"==typeof e?B:x}return function(t){return{encrypt:function(r,i,n){return e(i).encrypt(t,r,i,n)},decrypt:function(r,i,n){return e(i).decrypt(t,r,i,n)}}}}()}),h=(i.StreamCipher=d.extend({_doFinalize:function(){var e=this._process(!0);return e},blockSize:1}),r.mode={}),u=i.BlockCipherMode=n.extend({createEncryptor:function(e,t){return this.Encryptor.create(e,t)},createDecryptor:function(e,t){return this.Decryptor.create(e,t)},init:function(e,t){this._cipher=e,this._iv=t}}),l=h.CBC=function(){function e(e,r,i){var n=this._iv;if(n){var c=n;this._iv=t}else var c=this._prevBlock;for(var o=0;o<i;o++)e[r+o]^=c[o]}var r=u.extend();return r.Encryptor=r.extend({processBlock:function(t,r){var i=this._cipher,n=i.blockSize;e.call(this,t,r,n),i.encryptBlock(t,r),this._prevBlock=t.slice(r,r+n)}}),r.Decryptor=r.extend({processBlock:function(t,r){var i=this._cipher,n=i.blockSize,c=t.slice(r,r+n);i.decryptBlock(t,r),e.call(this,t,r,n),this._prevBlock=c}}),r}(),_=r.pad={},v=_.Pkcs7={pad:function(e,t){for(var r=4*t,i=r-e.sigBytes%r,n=i<<24|i<<16|i<<8|i,o=[],s=0;s<i;s+=4)o.push(n);var a=c.create(o,i);e.concat(a)},unpad:function(e){var t=255&e.words[e.sigBytes-1>>>2];e.sigBytes-=t}},y=(i.BlockCipher=d.extend({cfg:d.cfg.extend({mode:l,padding:v}),reset:function(){d.reset.call(this);var e=this.cfg,t=e.iv,r=e.mode;if(this._xformMode==this._ENC_XFORM_MODE)var i=r.createEncryptor;else{var i=r.createDecryptor;this._minBufferSize=1}this._mode&&this._mode.__creator==i?this._mode.init(this,t&&t.words):(this._mode=i.call(r,this,t&&t.words),this._mode.__creator=i)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else{var t=this._process(!0);e.unpad(t)}return t},blockSize:4}),i.CipherParams=n.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}})),m=r.format={},k=m.OpenSSL={stringify:function(e){var t=e.ciphertext,r=e.salt;if(r)var i=c.create([1398893684,1701076831]).concat(r).concat(t);else var i=t;return i.toString(a)},parse:function(e){var t=a.parse(e),r=t.words;if(1398893684==r[0]&&1701076831==r[1]){var i=c.create(r.slice(2,4));r.splice(0,4),t.sigBytes-=16}return y.create({ciphertext:t,salt:i})}},x=i.SerializableCipher=n.extend({cfg:n.extend({format:k}),encrypt:function(e,t,r,i){i=this.cfg.extend(i);var n=e.createEncryptor(r,i),c=n.finalize(t),o=n.cfg;return y.create({ciphertext:c,key:r,iv:o.iv,algorithm:e,mode:o.mode,padding:o.padding,blockSize:e.blockSize,formatter:i.format})},decrypt:function(e,t,r,i){i=this.cfg.extend(i),t=this._parse(t,i.format);var n=e.createDecryptor(r,i).finalize(t.ciphertext);return n},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}}),g=r.kdf={},S=g.OpenSSL={execute:function(e,t,r,i){i||(i=c.random(8));var n=p.create({keySize:t+r}).compute(e,i),o=c.create(n.words.slice(t),4*r);return n.sigBytes=4*t,y.create({key:n,iv:o,salt:i})}},B=i.PasswordBasedCipher=x.extend({cfg:x.cfg.extend({kdf:S}),encrypt:function(e,t,r,i){i=this.cfg.extend(i);var n=i.kdf.execute(r,e.keySize,e.ivSize);i.iv=n.iv;var c=x.encrypt.call(this,e,t,n.key,i);return c.mixIn(n),c},decrypt:function(e,t,r,i){i=this.cfg.extend(i),t=this._parse(t,i.format);var n=i.kdf.execute(r,e.keySize,e.ivSize,t.salt);i.iv=n.iv;var c=x.decrypt.call(this,e,t,n.key,i);return c}})}()});
//# sourceMappingURL=cipher-core.min.js.map
!function(e,i){"object"==typeof exports?module.exports=exports=i(require("./core.min")):"function"==typeof define&&define.amd?define(["./core.min"],i):i(e.CryptoJS)}(this,function(e){!function(){var i=e,t=i.lib,n=t.Base,s=i.enc,r=s.Utf8,o=i.algo;o.HMAC=n.extend({init:function(e,i){e=this._hasher=new e.init,"string"==typeof i&&(i=r.parse(i));var t=e.blockSize,n=4*t;i.sigBytes>n&&(i=e.finalize(i)),i.clamp();for(var s=this._oKey=i.clone(),o=this._iKey=i.clone(),a=s.words,f=o.words,c=0;c<t;c++)a[c]^=1549556828,f[c]^=909522486;s.sigBytes=o.sigBytes=n,this.reset()},reset:function(){var e=this._hasher;e.reset(),e.update(this._iKey)},update:function(e){return this._hasher.update(e),this},finalize:function(e){var i=this._hasher,t=i.finalize(e);i.reset();var n=i.finalize(this._oKey.clone().concat(t));return n}})}()});
//# sourceMappingURL=hmac.min.js.map
!function(e,o,r){"object"==typeof exports?module.exports=exports=o(require("./core.min"),require("./cipher-core.min")):"function"==typeof define&&define.amd?define(["./core.min","./cipher-core.min"],o):o(e.CryptoJS)}(this,function(e){return e.mode.ECB=function(){var o=e.lib.BlockCipherMode.extend();return o.Encryptor=o.extend({processBlock:function(e,o){this._cipher.encryptBlock(e,o)}}),o.Decryptor=o.extend({processBlock:function(e,o){this._cipher.decryptBlock(e,o)}}),o}(),e.mode.ECB});
//# sourceMappingURL=mode-ecb.min.js.map
!function(e,r,i){"object"==typeof exports?module.exports=exports=r(require("./core.min"),require("./cipher-core.min")):"function"==typeof define&&define.amd?define(["./core.min","./cipher-core.min"],r):r(e.CryptoJS)}(this,function(e){return e.pad.Pkcs7});
//# sourceMappingURL=pad-pkcs7.min.js.map
!function(e,r,i){"object"==typeof exports?module.exports=exports=r(require("./core.min"),require("./enc-base64.min"),require("./md5.min"),require("./evpkdf.min"),require("./cipher-core.min")):"function"==typeof define&&define.amd?define(["./core.min","./enc-base64.min","./md5.min","./evpkdf.min","./cipher-core.min"],r):r(e.CryptoJS)}(this,function(e){return function(){var r=e,i=r.lib,n=i.BlockCipher,o=r.algo,t=[],c=[],s=[],f=[],a=[],d=[],u=[],v=[],h=[],y=[];!function(){for(var e=[],r=0;r<256;r++)r<128?e[r]=r<<1:e[r]=r<<1^283;for(var i=0,n=0,r=0;r<256;r++){var o=n^n<<1^n<<2^n<<3^n<<4;o=o>>>8^255&o^99,t[i]=o,c[o]=i;var p=e[i],l=e[p],_=e[l],k=257*e[o]^16843008*o;s[i]=k<<24|k>>>8,f[i]=k<<16|k>>>16,a[i]=k<<8|k>>>24,d[i]=k;var k=16843009*_^65537*l^257*p^16843008*i;u[o]=k<<24|k>>>8,v[o]=k<<16|k>>>16,h[o]=k<<8|k>>>24,y[o]=k,i?(i=p^e[e[e[_^p]]],n^=e[e[n]]):i=n=1}}();var p=[0,1,2,4,8,16,32,64,128,27,54],l=o.AES=n.extend({_doReset:function(){if(!this._nRounds||this._keyPriorReset!==this._key){for(var e=this._keyPriorReset=this._key,r=e.words,i=e.sigBytes/4,n=this._nRounds=i+6,o=4*(n+1),c=this._keySchedule=[],s=0;s<o;s++)if(s<i)c[s]=r[s];else{var f=c[s-1];s%i?i>6&&s%i==4&&(f=t[f>>>24]<<24|t[f>>>16&255]<<16|t[f>>>8&255]<<8|t[255&f]):(f=f<<8|f>>>24,f=t[f>>>24]<<24|t[f>>>16&255]<<16|t[f>>>8&255]<<8|t[255&f],f^=p[s/i|0]<<24),c[s]=c[s-i]^f}for(var a=this._invKeySchedule=[],d=0;d<o;d++){var s=o-d;if(d%4)var f=c[s];else var f=c[s-4];d<4||s<=4?a[d]=f:a[d]=u[t[f>>>24]]^v[t[f>>>16&255]]^h[t[f>>>8&255]]^y[t[255&f]]}}},encryptBlock:function(e,r){this._doCryptBlock(e,r,this._keySchedule,s,f,a,d,t)},decryptBlock:function(e,r){var i=e[r+1];e[r+1]=e[r+3],e[r+3]=i,this._doCryptBlock(e,r,this._invKeySchedule,u,v,h,y,c);var i=e[r+1];e[r+1]=e[r+3],e[r+3]=i},_doCryptBlock:function(e,r,i,n,o,t,c,s){for(var f=this._nRounds,a=e[r]^i[0],d=e[r+1]^i[1],u=e[r+2]^i[2],v=e[r+3]^i[3],h=4,y=1;y<f;y++){var p=n[a>>>24]^o[d>>>16&255]^t[u>>>8&255]^c[255&v]^i[h++],l=n[d>>>24]^o[u>>>16&255]^t[v>>>8&255]^c[255&a]^i[h++],_=n[u>>>24]^o[v>>>16&255]^t[a>>>8&255]^c[255&d]^i[h++],k=n[v>>>24]^o[a>>>16&255]^t[d>>>8&255]^c[255&u]^i[h++];a=p,d=l,u=_,v=k}var p=(s[a>>>24]<<24|s[d>>>16&255]<<16|s[u>>>8&255]<<8|s[255&v])^i[h++],l=(s[d>>>24]<<24|s[u>>>16&255]<<16|s[v>>>8&255]<<8|s[255&a])^i[h++],_=(s[u>>>24]<<24|s[v>>>16&255]<<16|s[a>>>8&255]<<8|s[255&d])^i[h++],k=(s[v>>>24]<<24|s[a>>>16&255]<<16|s[d>>>8&255]<<8|s[255&u])^i[h++];e[r]=p,e[r+1]=l,e[r+2]=_,e[r+3]=k},keySize:8});r.AES=n._createHelper(l)}(),e.AES});
//# sourceMappingURL=aes.min.js.map
!function(e,n){"object"==typeof exports?module.exports=exports=n(require("./core.min")):"function"==typeof define&&define.amd?define(["./core.min"],n):n(e.CryptoJS)}(this,function(e){return e.enc.Utf8});
//# sourceMappingURL=enc-utf8.min.js.map

pad-nopadding.js文件

/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
/**
 * A noop padding strategy.
 */
CryptoJS.pad.NoPadding = {
    pad: function () {
    },

    unpad: function () {
    }
};

有人可能会说,我这边用明文是“1111111111111111”,你是把“1”当作字符,十六进制则是0x31,如果我写的是"31313131313131313131313131313131",每个31是十六进制数呢?

思路区别:

当我使用的是字符"1"时,加密数据、key等使用如下形式进行格式转换操作     var key = CryptoJS.enc.Utf8.parse(1111111111111111);;

当我使用"31"表示十六进制0x31时,使用以下方式转换:var key = CryptoJS.enc.Hex.parse("31313131313131313131313131313131");

二、AES-CCM加密解密操作

java部分:

1、我是使用的maven作为java环境的创建,首先需要导入加密的jar文件,pom.xml中需要添加

<dependency>
		<groupId>org.bouncycastle</groupId>
		<artifactId>bcprov-jdk15on</artifactId>
		<version>1.58</version>
</dependency>

2、编写java代码:

package LinkpowerLock.AES.CCM;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import LinkpowerLock.AES.ECB.ECBHardTest;

public class AesCcm {
	/**
	 * 
	 * @param context byte 16 context
	 * @param nonce nonce 
	 * @param keyBytes keyֵ
	 * @param wheterDecrypt 是否执行解密
	 * @return byte[]
	 */
	public static byte[] whetherDecrypt(byte[] context,byte[] nonce,byte[] keyBytes,boolean wheterDecrypt) {
		Security.addProvider(new BouncyCastleProvider());
		//避免出现java.lang.IllegalArgumentException: iv == null
		if(nonce == null) {
			return null;
		}
		byte[] bs = null;
		//32   mac 
        GCMParameterSpec parameterSpec = new GCMParameterSpec(32, nonce);
        byte[] header = { '1','2','3','4','5','6','7','8','9','a','b','c','d','e' };
        try {
			Cipher cipher = Cipher.getInstance("AES/CCM/NoPadding");
			SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
			if(!wheterDecrypt) {
				//加密
				cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, parameterSpec);
			}else {
				//解密
				cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, parameterSpec);
				
			}
			cipher.updateAAD(header);
			bs = cipher.doFinal(context);
			
			
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return bs;
		} catch (InvalidAlgorithmParameterException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			//mac check in ccm failed
			return bs;
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        return bs;
	}
	
	public static void main(String[] args) {
		byte[] content = {0x01,0x6e,0x04,0x08,0x08,0x06,0x06,0x00,0x00
				,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		byte[] key = {0x39,0x50,0x41,0x4e,0x30,0x2e,0x33,0x30,0x36,0x22
				,0x2c,0x22,0x56,0x65,0x6e,0x31};
		byte[] nonce = {(byte) 0xf1,(byte) 0x8e,0x08,(byte) 0x89,0x1a,0x38,0x5f,0x7f,0x0d,0x5d,0x5a,0x43};
		byte[] encryptVal = whetherDecrypt(content,nonce,key,false);
		//System.out.println(Arrays.toString(encryptVal));
		System.out.println(ECBHardTest.parseByte2HexStr(encryptVal));
	}
}

js部分代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
	</body>
	<script src="asmcrypto.all.es5.js" type="text/javascript" charset="utf-8"></script>
	<!--<script src="../ecb/aes.js" type="text/javascript" charset="utf-8"></script>-->
	<script type="text/javascript">
		window.onload = function(){
			var content = "016e0408080606000000000000000000";//明文
			var keys = "3950414e302e333036222c2256656e31";//加密解密的key
			var nonce = "f18e08891a385f7f0d5d5a43";//nonce值
			
			//开锁密钥(16字节)
			var openLock = "016e0400000000000000000000000000";
			
			//加密文件  需要解密 
			console.log("加密结果:"+asmCrypto.bytes_to_hex(encryPt(content,keys,nonce))) 
			console.log("解密结果:"+asmCrypto.bytes_to_hex(decryPt("7a6948089a5f80eea5b52caa5a2e58463154b1ea",keys,nonce))) 
			
		}
		//加密
		function encryPt(contentVal,keyVal,nonceVal){ 
			
			var hander = asmCrypto.hex_to_bytes("3132333435363738396162636465");
			const content = asmCrypto.hex_to_bytes(contentVal);
			const keys = asmCrypto.hex_to_bytes(keyVal);
			const nonce = asmCrypto.hex_to_bytes(nonceVal);
			return asmCrypto.AES_CCM.encrypt(content,keys,nonce,hander,4)
		}
		
		//解密
		function decryPt(contentVal,keyVal,nonceVal){
//和java代码的key保持一致
			var hander = asmCrypto.hex_to_bytes("3132333435363738396162636465");
			const content = asmCrypto.hex_to_bytes(contentVal);
			console.log("content-> "+asmCrypto.bytes_to_hex(content));
			const keys = asmCrypto.hex_to_bytes(keyVal);
			console.log("keys-> "+asmCrypto.bytes_to_hex(keys));
			const nonce = asmCrypto.hex_to_bytes(nonceVal);
			console.log("nonce-> "+asmCrypto.bytes_to_hex(nonce));
			//const nonce = CryptoJS.enc.Hex.parse(nonceVal);
			//const adata = new Uint8Array(8);
			//console.log("adata-> "+asmCrypto.bytes_to_hex(adata));
			
			
			return asmCrypto.AES_CCM.decrypt(content,keys,nonce,hander,4);
		}
	</script>
</html>

运行结果:

js:

[Web浏览器] "加密结果:7a6948089a5f80eea5b52caa5a2e58463154b1ea"	/wanwan/html/ccm/aes-ccmTest.html (27)
[Web浏览器] "content-> 7a6948089a5f80eea5b52caa5a2e58463154b1ea"	/wanwan/html/ccm/aes-ccmTest.html (57)
[Web浏览器] "keys-> 3950414e302e333036222c2256656e31"	/wanwan/html/ccm/aes-ccmTest.html (59)
[Web浏览器] "nonce-> f18e08891a385f7f0d5d5a43"	/wanwan/html/ccm/aes-ccmTest.html (61)
[Web浏览器] "解密结果:016e0408080606000000000000000000"	/wanwan/html/ccm/aes-ccmTest.html (28)

java:

7A6948089A5F80EEA5B52CAA5A2E58463154B1EA 

之前直接贴出js加密解密库文件,页面太卡顿影响了大家的查看心情,现换成链接获取。

js库文件,asmcrypto.all.es5.js  下载路径。