赞
踩
This memo specifies an authentication algorithm based on CMAC with the 128-bit Advanced Encryption Standard (AES). This new authentication algorithm is named AES-CMAC.
AES-CMAC可以检测有意图的,未鉴权的数据修改,也包括意外修改。
AES比hash函数更容易使用。
见原文。

如果Message的size是128bit的整数倍,最后一个block在AES_K运算之前要和K1进行XOR运算;否则,最后一个block会使用10^i填充到128bit,并且在AES_K运算之前和K2进行XOR运算。
AES_K:使用秘钥K的AES-128。
M:message,被切分成了M_1,M_2,……, M_n, M_i就表示第i个block。M_1到M_n-1的长度都是128bits。M_n 的长度是≤128bits。
K1和K2是子密钥生成算法生成的两个子密钥。
子密钥生成算法的输入输出表示:(K1,K2) := Generate_Subkey(K),K就是AES-128的秘钥,K1和K2就是算法输出结果,两个子密钥。

MAC生成算法被表示为:T := AES-CMAC(K,M,len),K表示秘钥,M就是要保护的message,len是消息长度(单位为octets)。校验MAC可以确定消息的完整性(integrity)和鉴权(authenticity)。

n就是block个数, flag就表示是否被整除了,true表示正好是128的整数倍,false表示反之。

由AES算法提供安全性保证。 AES或者其他加密算法的优势部分在于秘钥K和实现的正确性。密钥的生成方式应满足 RFC 4086的伪随机性要求,并应安全保存。 当且仅当正确使用 AES-CMAC 时,它才能提供满足当前消息身份验证最佳实践的身份验证和完整性。
见原文:https://datatracker.ietf.org/doc/html/rfc4493
见原文。
from .abscipheralgo import AbsCipherAlgo class CmacAlgo: byte_limit = 16 bit_limit = 128 const_rb = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87') const_zero = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') def xor_bit_limit(self, a:bytearray, b:bytearray) -> bytearray: assert len(a) == self.byte_limit assert len(b) == self.byte_limit out = bytearray(self.byte_limit) for i in range(self.byte_limit): out[i] = a[i] ^ b[i] return out def left_shift_one_bit(self, input:bytearray) -> bytearray: assert len(input) == self.byte_limit overflow = bytearray(1) output = bytearray(self.byte_limit) for i in reversed(range(self.byte_limit)): # make sure is a byte output[i] = (input[i] << 1) & 0xFF output[i] |= overflow[0] overflow[0] = 1 if (input[i] & 0x80) else 0 return output def generate_subkey(self, key: bytearray, cipher_algo:AbsCipherAlgo): L = bytearray(self.byte_limit) Z = bytearray(self.byte_limit) tmp = bytearray(self.byte_limit) for i in range(self.byte_limit): Z[i] = 0 L = cipher_algo.encrypt(key, Z) # If MSB(L) = 0, then K1 = L << 1 if (L[0] & 0x80) == 0: K1 = self.left_shift_one_bit(L) else: tmp = self.left_shift_one_bit(L) K1 = self.xor_bit_limit(tmp, self.const_rb) if K1[0] & 0x80 == 0: K2 = self.left_shift_one_bit(K1) else: tmp = self.left_shift_one_bit(K1) K2 = self.xor_bit_limit(tmp, self.const_rb) return K1,K2 """ 将最后一个block以10^i的方式补齐 """ def padding(self, last_block: bytearray): assert last_block is not None pad = bytearray(self.byte_limit) for j in range(self.byte_limit): if j < len(last_block): pad[j] = last_block[j] elif j == len(last_block): pad[j] = 0x80 else: pad[j] = 0x00 return pad def cmac(self, key: bytearray, input:bytearray, cipher_algo:AbsCipherAlgo) -> bytes: K1, K2 = self.generate_subkey(key, cipher_algo) # n is number of rounds # c语言直接除,因为int截断 n = (len(input) + self.byte_limit - 1) // self.byte_limit if n == 0: n = 1 # last block is not a complete block flag = 0 else: # last block is a complete block if len(input) % self.byte_limit == 0: flag = 1 else: flag = 0 # 计算M_last # last block is complete if flag: M_last = self.xor_bit_limit(input[(n - 1) * self.byte_limit : ], K1) else: padded = self.padding(input[(n - 1) * self.byte_limit : ]) M_last = self.xor_bit_limit(padded, K2) X = bytearray(self.byte_limit) for i in range(self.byte_limit): X[i] = 0 for i in range(n-1): Y = self.xor_bit_limit(X, input[self.byte_limit * i : self.byte_limit * (i + 1)]) X = cipher_algo.encrypt(key, Y) Y = self.xor_bit_limit(X, M_last) X = cipher_algo.encrypt(key, Y) mac = bytearray(self.byte_limit) for i in range(self.byte_limit): mac[i] = X[i] return mac
from .cmacalgo import CmacAlgo
class Cmac128Algo(CmacAlgo):
const_rb = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87')
const_zero = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
def __init__(self):
self.byte_limit = 16
self.bit_limit = 128
self.const_rb = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87')
self.const_zero = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
from .cmacalgo import CmacAlgo
class Cmac256Algo(CmacAlgo):
const_rb = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87')
const_zero = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
def __init__(self):
self.byte_limit = 32
self.bit_limit = 256
const_rb = bytearray(
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87')
const_zero = bytearray(
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
Cryptography:https://blog.51cto.com/u_16175518/6765321
CryptSM4:https://cloud.tencent.com/developer/article/1751336?areaId=106001
https://github.com/yang3yen/pysm4
算法padding模式:PKCS7,None
明文:
0x40, 0x10, 0xFF, 0xEF, 0x00, 0x45, 0x93, 0x00, 0xAB, 0xCD, 0xEE, 0x00, 0xF0, 0xF4, 0x00, 0x88,
0xA2, 0x19, 0x09, 0x67, 0x87, 0x0C, 0xFF, 0x54, 0xF3, 0x12, 0x50, 0x33, 0xC7, 0xF9, 0x1F, 0xDF,
0x13, 0x73, 0x4F, 0x67, 0xD7, 0xEB, 0xCC, 0x44, 0xF1, 0x12, 0x90, 0x18, 0xA7, 0xA9, 0x1F, 0x03,
0x13, 0x88, 0x4F, 0x67, 0xD7, 0xEB, 0xCC, 0x44, 0xF1, 0x12, 0x46, 0x18, 0x64, 0xA9, 0x1F, 0xEE,
密钥:
0x23, 0x33, 0x41, 0x67, 0x87, 0xEB, 0xFF, 0x54, 0xF1, 0x12, 0x90, 0x11, 0xC7, 0xF9, 0x1F, 0x23
ECB密文:
0x92, 0x31, 0xc8, 0x55, 0xcb, 0x47, 0x0b, 0x07, 0x93, 0x1d, 0xff, 0xb8, 0x14, 0x23, 0x4c, 0x63,
0x06, 0xc9, 0x57, 0x3f, 0x37, 0x12, 0x3b, 0x54, 0xef, 0x61, 0xb6, 0x82, 0x18, 0x83, 0x1f, 0xa2,
0x8a, 0xb6, 0xa9, 0xcc, 0x02, 0xa7, 0xd3, 0x26, 0xeb, 0xeb, 0xe4, 0x5a, 0x48, 0xab, 0xb2, 0xe1,
0x5b, 0x38, 0x67, 0xe9, 0xb4, 0x16, 0x47, 0x6a, 0x0a, 0xf3, 0x9b, 0xef, 0x12, 0xb0, 0x28, 0xb5,
CBC密文:
0x0f, 0xa7, 0x44, 0xda, 0xba, 0x7c, 0x9d, 0xe3, 0xc3, 0xde, 0xab, 0xe7, 0x42, 0x4f, 0x29, 0x68,
0xa2, 0xdd, 0x8e, 0x21, 0x60, 0xd5, 0xbd, 0x5f, 0xf1, 0x63, 0x7e, 0xa7, 0xb2, 0xdf, 0x3f, 0x89,
0x73, 0xc9, 0x72, 0xe6, 0x69, 0x2d, 0xee, 0x23, 0xe5, 0x10, 0xd7, 0x57, 0x7d, 0xc2, 0x1f, 0x0b,
0x6f, 0x12, 0x51, 0x6d, 0xc3, 0x28, 0x2b, 0x07, 0xee, 0xd2, 0x56, 0x05, 0x22, 0x1e, 0x3d, 0xad,
明文:
0x40, 0x10, 0xFF, 0xEF, 0x00, 0x45, 0x93, 0x00, 0xAB, 0xCD, 0xEE, 0x00, 0xF0, 0xF4, 0x00, 0x88,
0xA2, 0x19, 0x09, 0x67, 0x87, 0x0C, 0xFF, 0x54, 0xF3, 0x12, 0x50, 0x33, 0xC7, 0xF9, 0x1F, 0xDF,
0x13, 0x73, 0x4F, 0x67, 0xD7, 0xEB, 0xCC, 0x44, 0xF1, 0x12, 0x90, 0x18, 0xA7, 0xA9, 0x1F, 0x03,
0x13, 0x88, 0x4F, 0x67, 0xD7, 0xEB, 0xCC, 0x44, 0xF1, 0x12, 0x46, 0x18, 0x64, 0xA9, 0x1F, 0xEE,
密钥:
0x23, 0x33, 0x41, 0x67, 0x87, 0xEB, 0xFF, 0x54, 0xF1, 0x12, 0x90, 0x11, 0xC7, 0xF9, 0x1F, 0x23
CMAC密文:
0xb0, 0xeb, 0x38, 0x61, 0xe6, 0xc5, 0xc1, 0x09, 0x89, 0x61, 0x30, 0x7d, 0x49, 0xb1, 0x7a, 0x7d
[1] https://datatracker.ietf.org/doc/html/rfc4493
[2] 国密算法库:https://github.com/duanhongyi/gmssl
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。