AES加密之CryptoJS与Java C#互相加密解密

CryptoJS的AES加密有两种方式

1. 密码password是string类型的:

CryptoJS.AES.encrypt("123456","123456")//(data,password)

    这种方式使用指定的iv也无效,默认使用"AES/CBC/PKCS7Padding"

    加密过程:

    先生产8字节的salt,再使用 EvpKDF函数传入salt(字节码形式)和password(字节码形式)参数生成Iv和Key

    再使用该Iv和Key进行AES加密,加密结果为

    Base64("Salted__"(固定字符串:字节码形式)+Salt(字节码形式)+密文 (字节码形式))

    所以每次加密的结果前几个字符都是一样的

   EvpKDF函数的Java代码

			byte[] kBuff = password.getBytes();
			byte[] saltBuff = new byte[8];

			byte[] keyBuff = new byte[32];
			byte[] ivBuff = new byte[16];
			EvpKDF(kBuff, 256, 128, saltBuff, keyBuff, ivBuff);

        /**
	 * 
	 * @param password
	 * @param keySize
	 *            单位 比特
	 * @param ivSize
	 *            单位 比特
	 * @param salt 盐
	 * @param resultKey 生成的key
	 * @param resultIv 生成的iv
	 * @return
	 * @throws NoSuchAlgorithmException
	 */
	public static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, byte[] resultKey,
			byte[] resultIv) throws NoSuchAlgorithmException {
		return EvpKDF(password, keySize, ivSize, salt, 1, "MD5", resultKey, resultIv);
	}

	/**
	 * 
	 * @param password
	 * @param keySize
	 *            单位 比特
	 * @param ivSize
	 *            单位 比特
	 * @param salt
	 *            盐
	 * @param iterations
	 *            循环次数
	 * @param hashAlgorithm
	 *            摘要算法
	 * @param resultKey
	 * @param resultIv
	 * @return
	 * @throws NoSuchAlgorithmException
	 */
	public static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, int iterations,
			String hashAlgorithm, byte[] resultKey, byte[] resultIv) throws NoSuchAlgorithmException {
		keySize = keySize / 32;
		ivSize = ivSize / 32;
		int targetKeySize = keySize + ivSize;// =8+4=12块
		byte[] derivedBytes = new byte[targetKeySize * 4];// 所需字节
		int numberOfDerivedWords = 0;// 4字节计数
		byte[] block = null;
		MessageDigest hasher = MessageDigest.getInstance(hashAlgorithm);
		while (numberOfDerivedWords < targetKeySize) {
			if (block != null) {
				hasher.update(block);
			}
			hasher.update(password);
			hasher.update(salt);
			block = hasher.digest();
			hasher.reset();

			// Iterations
			for (int i = 1; i < iterations; i++) {
				block = hasher.digest(block);
				hasher.reset();
			}

			System.arraycopy(block, 0, derivedBytes, numberOfDerivedWords * 4,
					Math.min(block.length, (targetKeySize - numberOfDerivedWords) * 4));

			numberOfDerivedWords += block.length / 4;
		}

		System.arraycopy(derivedBytes, 0, resultKey, 0, keySize * 4);
		System.arraycopy(derivedBytes, keySize * 4, resultIv, 0, ivSize * 4);

		return derivedBytes; // key + iv
	}

2 如果password是二进制形式

  则按照传统的AES方式进行加密,加密结果只有密文,不带其他信息

	var key= CryptoJS.enc.Hex.parse("0102030405060708000000000000000000000000000000000000000000000000");
	var iv=CryptoJS.enc.Hex.parse("00000000000000000000000000000000");
	var content=CryptoJS.enc.Hex.parse("010203040506070809");
	var ciphertext = CryptoJS.AES.encrypt(content, key, {   
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding:CryptoJS.pad.Pkcs7 
    });

加密结果 M9GSRWldlsYMy3Pbfg+x6Q==

至于如何解密,知道了加密方式,解密也就迎刃而解了。


第一种方法的js解密,比较简单

CryptoJS.AES.decrypt($("密文(字符串形式)","123456")

第二种方法的解密方法,逆过来就可以了。

至于使用Java C# 如果解密  CryptoJS生成的密文,分析上面的过程,

很容易就可以写出相关的代码,就不在这里献丑了。需要强调的是

CryptoJS 密文默认是使用Base64编码,明文先将字符串转成utf-8的字节码 

password直接转成utf-8的字节码即可。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值