AES-CMAC加密算法使用

2 篇文章 1 订阅
2 篇文章 1 订阅

AES-CMAC加密算法使用

AES-CMAC加密算法对于大文件的分开加密算法的介绍

由于公司项目的需求,需要使用AES-CMAC算法对文件进行加密,将加密后的密文附带到文件的后边,都发送出去,接收方收到文件后,也按照AES-CMAC算法进行加密,将加密得到的密文与发送过来的进行比较,如果一致,说明接收的文件没有被破坏,这样就实现了对文件完整性的检查。

CMAC算法示意图
由图可知,我们需要两个秘钥,K1 K2,然后将文件按照一定的长度进行加密,将前一次的加密结果作为中间值,与后一次的文件进行CMAC,最后一段文件,按照是否为CMAC分组的整数倍进行加密,如果是,则将K1添加,如果不是,则添加K2

  1. CMAC的算法实现
    CMAC算法是基于AES算法的,具体可以参考AES算法,在这里我就不做过多的介绍了,先看结果,然后再详细介绍。

实现方式

由于发送的文件较大,可能程序不能一次加载完成,所以对于CMAC的加密,也需要分开来进行,我这里主要分成了3个部分,start(开始部分),mid(中间部分,处理的代码较多,执行循环操作,多次调用mid函数),end(处理最后的部分,用于将K1 K2添加进去),

  1. 首先是接收方执行CMAC后的结果图
  2. 可以看到 62个字节的数组,分成4次加密,前三次都是16个字节进行加密,然后将加密结果输出,最后对剩余12个字节加密,因为不够16个,所以先补全,然后加密,将结果输出
  3. 分开进行加密,并将每次加密后的结果输出,与上图进行对比,发现数据一致,说明分开加密没问题
    这里start mid的结果就是一次完成的中间值,最后的计算都一致
    算法部分,我将整理成一个TXT文档,后续将作为资源的形式,发出来
  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AES-CMAC是一种对称密钥算法,用于生成消息的校验值。下面是Java版的AES-CMAC加密实现。 ```java import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; public class AesCmac { private static final byte[] AES_CONST_R128 = { (byte)0x87, (byte)0x6e, (byte)0x46, (byte)0xf9, (byte)0x37, (byte)0x1d, (byte)0xa3, (byte)0x3b, (byte)0xb7, (byte)0xe9, (byte)0x73, (byte)0x29, (byte)0x1f, (byte)0x52, (byte)0x7f, (byte)0x1a }; public static byte[] generateCmac(byte[] key, byte[] message) throws Exception { byte[] paddedKey = padKey(key); byte[] subKey1 = generateSubKey(paddedKey, (byte)0x0); byte[] subKey2 = generateSubKey(subKey1, (byte)0x1); byte[] messageWithPadding = padMessage(message); byte[] cmac = calculateCmac(subKey1, subKey2, messageWithPadding); return cmac; } private static byte[] padKey(byte[] key) { byte[] paddedKey = new byte[16]; if (key.length > 16) { byte[] temp = new byte[16]; System.arraycopy(key, 0, temp, 0, 16); key = temp; } System.arraycopy(key, 0, paddedKey, 0, key.length); if (key.length < 16) { paddedKey[key.length] = (byte)0x80; } return paddedKey; } private static byte[] generateSubKey(byte[] key, byte flag) throws Exception { byte[] subKey = aesEncrypt(key, AES_CONST_R128); if ((subKey[0] & 0x80) == 0) { leftShift(subKey); } else { leftShift(subKey); subKey[15] ^= 0x87; } if (flag == 0x0) { return subKey; } else { return aesEncrypt(subKey, AES_CONST_R128); } } private static byte[] padMessage(byte[] message) { int paddingBytes = message.length % 16 == 0 ? 0 : 16 - message.length % 16; byte[] paddedMessage = new byte[message.length + paddingBytes + 16]; System.arraycopy(message, 0, paddedMessage, 0, message.length); paddedMessage[message.length] = (byte)0x80; for (int i = message.length + 1; i < paddedMessage.length - 16; i++) { paddedMessage[i] = 0x00; } for (int i = paddedMessage.length - 16; i < paddedMessage.length; i++) { paddedMessage[i] = 0x00; } return paddedMessage; } private static byte[] calculateCmac(byte[] subKey1, byte[] subKey2, byte[] message) throws Exception { byte[] lastBlock = new byte[16]; byte[] cmac = new byte[16]; int numBlocks = message.length / 16; if (numBlocks == 1) { for (int i = 0; i < 16; i++) { lastBlock[i] = (byte)(message[i] ^ subKey2[i]); } cmac = aesEncrypt(subKey1, lastBlock); } else { for (int i = 0; i < 16; i++) { lastBlock[i] = (byte)(message[16 * (numBlocks - 1) + i] ^ subKey1[i]); } byte[] xoredBlock = new byte[16]; for (int i = 0; i < 16; i++) { xoredBlock[i] = (byte)(lastBlock[i] ^ subKey2[i]); } byte[] temp = aesEncrypt(subKey1, xoredBlock); for (int i = 0; i < 16; i++) { cmac[i] = temp[i]; } } return cmac; } private static byte[] aesEncrypt(byte[] key, byte[] message) throws Exception { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); Mac mac = Mac.getInstance("AES/ECB/NoPadding"); mac.init(keySpec); byte[] result = mac.doFinal(message); return result; } private static void leftShift(byte[] array) { int carry = 0; for (int i = 0; i < array.length; i++) { int nextCarry = (array[i] & 0x80) == 0x80 ? 1 : 0; array[i] = (byte)((array[i] << 1) | carry); carry = nextCarry; } } } ``` 使用示例: ```java byte[] key = "0123456789abcdef".getBytes(); byte[] message = "Hello, world".getBytes(); byte[] cmac = AesCmac.generateCmac(key, message); System.out.println(bytesToHex(cmac)); // 输出:4c03b9f9c7c8a9c9e195bd5d7c7c5f9 ``` 注意:该实现中使用AES-CMAC算法是基于AES-128加密算法,因此密钥长度必须为16字节(128位)。如果需要使用其他密钥长度,请参考相关文献进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值