[Calculate CMAC value based on AES-128]

Preface

Simply use Qt to develop a small tool to calculate the CMAC value of a binary file. The user selects a binary file and then enters the key value to calculate the CMAC value. This article will give the implementation code. I will briefly introduce what AES encryption and CAMC are. Let’s get straight to the point.

AES

AES (Advanced Encryption Standard) is a symmetric encryption algorithm that is widely used to protect the security of sensitive data. AES is designed to provide a high degree of security and to run efficiently on a variety of devices.
The AES algorithm has three fixed key lengths: 128 bits, 192 bits and 256 bits. Among them, AES-128 uses a key length of 128 bits (16 bytes). The following are some key features of AES-128:
1. Key length: AES-128 uses a 128-bit (16-byte) key. is the basic security level of the algorithm. The length of the key directly affects the security of the algorithm. Longer keys generally provide higher security, but also increase computational complexity.
2. Packet length: AES-128 divides the data into 128-bit (16-byte) blocks for encryption. This is the fixed packet length in the AES algorithm.
3. Number of rounds: AES-128 uses 10 rounds of encryption iterations. Each round involves different operations, including substitution of bytes, row shifting, column obfuscation, and round key addition. Together, these operations enhance the security of the algorithm.
4. Substitution byte (SubBytes): In the substitution byte stage, each byte will be replaced with a predefined byte, through S Substitution Box. This step increases the nonlinearity of the algorithm and improves security.
5. Row shift (ShiftRows): In the row shift stage, each row in AES-128 will be cyclically shifted to the left according to fixed rules. This step helps to increase the obfuscation of the data.
6. Column confusion (MixColumns): Column confusion is a linear transformation that increases the complexity of the algorithm by multiplying each column by a fixed matrix. .
7. Round key addition (AddRoundKey): In each round, the round key will perform a bitwise XOR operation with the data block. The round key is expanded from the master key and generated through a series of key expansion algorithms.

CMAC

CMAC (Cipher-based Message Authentication Code) is a password-based message authentication code algorithm. It is a deterministic key-related function used to calculate the authentication code of a message to verify the integrity and authenticity of the message. CMAC evolved from CBC-MAC (Cipher Block Chaining Message Authentication Code), but solved some security issues in design.
CMAC has two main stages: generation and verification.
Generation phase:
Enter message and key.
Use an encryption algorithm to process the message and generate a fixed-length authentication code.
Verification phase:
Enter message, key and authentication code.
Use the encryption algorithm to process the message and generate a new authentication code.
Compares the generated authentication code with the entered authentication code. If the two match, the message is verified as complete and authentic.
CMAC provides a secure way to authenticate messages without using digital signatures. It is suitable for various applications, such as network communication, file transfer, etc., to ensure that messages have not been tampered with during transmission.

One specific implementation of CMAC is to use the AES (Advanced Encryption Standard) algorithm, so in some contexts, CMAC is also called AES-CMAC.

accomplish

openssl

OpenSSL is an open source cryptography toolkit that provides a series of encryption algorithms and implementation of secure communication protocols. It supports a variety of operating systems, including Unix-like systems such as Linux and BSD, as well as Windows. The following are some of the main features and usage of OpenSSL:
Encryption algorithm: OpenSSL provides a series of encryption algorithms, including symmetric encryption algorithms (such as AES, DES, 3DES ), asymmetric encryption algorithms (such as RSA, DSA, ECDSA), hash functions (such as MD5, SHA-1, SHA-256), etc. These algorithms can be used for data encryption, digital signatures, message authentication codes, etc.
SSL/TLS protocol: OpenSSL implements the SSL (Secure Sockets Layer) and TLS (Transport Layer Security) protocols for secure network communication. It supports multiple protocol versions including SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3. The SSL/TLS protocol is used to establish an encrypted communication channel between the client and server, ensuring data confidentiality and integrity.
Command line tools: OpenSSL provides some command line tools, the most commonly used of which is the openssl command. Through the openssl command, users can perform various operations, such as generating key pairs, creating digital certificates, performing encryption and decryption operations, etc.

calculateFileCMAC

This function will be executed when the user selects a file on the interface.
Parameters:
key: Key, length is AES_BLOCK_SIZE.
filePath: The file path for which CMAC needs to be calculated.
Operation steps:
1. Open the file and read all the data in the file.
2. If the length of the file data is less than 64KB, padding is performed, and the padding data is 0xFF.
3. Call the calculateCMAC function to calculate the CMAC of the file and return the result.

calculateCMAC

This function will be executed after reading the file data
Parameters:
key: key, length is AES_BLOCK_SIZE (usually 16 bytes) .
data: Data needed to calculate CMAC.
Operation steps:
Check whether the key length is correct. If it is incorrect, an error message will be output and an empty QByteArray will be returned.
Create a CMAC context (CMAC_CTX).
Perform byte order flipping on the input data (flip every four bytes).
Initialize the CMAC context using the OpenSSL function CMAC_Init, specifying the AES-128-CBC algorithm.
Use CMAC_Update to update the CMAC context to add data to the calculation.
Use CMAC_Final to complete the CMAC calculation and obtain the final authentication code.
Convert the authentication code to the result of QByteArray type.
Releases the CMAC context.
File processing:
Create a new file path based on the original file path and copy the file to the new path.
Appends the calculated CMAC in a new file.
Display the calculated CMAC in hexadecimal form in the text edit box of the interface.
Create a new file and write the flipped data to the new file.

key code

calculateFileCMAC:

QByteArray cmacopenssl::calculateFileCMAC(const QByteArray &key, const QString &filePath)
{
    
    
    QByteArray result;

    // Read the content of the file
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
    
    
        qDebug() << "Failed to open file:" << file.errorString();
        return result;
    }
    //qint64 fileSize = file.size();
    QByteArray fileData = file.readAll();
    file.close();
    //fileData = QByteArray::fromHex("aaaaaaaaaa");
    // Calculate CMAC for the file data
    // Check the length of the fileData
    qint64 dataSize = fileData.size();
    qint64 paddingSize = 64 * 1024 - dataSize;

    // Check if padding is needed
    if (paddingSize > 0) {
    
    
        QByteArray paddingData(paddingSize, '\xff');
        //fileData.append(paddingData);
    }
    //qDebug()<<fileData.toHex();
    qDebug()<<"size:  "<<fileData.size();
    qDebug()<<fileData.toHex();
    result = calculateCMAC(key, fileData);
    return result;
}

calculateCMAC:

QByteArray cmacopenssl::calculateCMAC(const QByteArray &key, const QByteArray &data)
{
    
    
    QByteArray result;
    // Check key length
    if (key.length() != AES_BLOCK_SIZE) {
    
    
        qDebug() << "Key length should be " << AES_BLOCK_SIZE << " bytes.";
        return result;
    }
    // Create a CMAC context
    CMAC_CTX *ctx = CMAC_CTX_new();
    // Reverse the endianness of every four bytes in the input data
    QByteArray reversedData = data;
    qDebug()<<reversedData.toHex();
    for (int i = 0; i < reversedData.size(); i += 4) {
    
    
        // Ensure that we have at least four bytes to convert
        if (i + 3 < reversedData.size()) {
    
    
            char temp = reversedData[i];
            reversedData[i] = reversedData[i + 3];
            reversedData[i + 3] = temp;

            temp = reversedData[i + 1];
            reversedData[i + 1] = reversedData[i + 2];
            reversedData[i + 2] = temp;
        }
    }
    // Initialize CMAC context with the key
    if (CMAC_Init(ctx, key.constData(), key.length(), EVP_aes_128_cbc(), nullptr) != 1) {
    
    
        qDebug() << "CMAC_Init failed.";
        CMAC_CTX_free(ctx);
        return result;
    }
    //Update CMAC context with the data
    if (CMAC_Update(ctx, data.constData(), data.length()) != 1) {
    
    
        qDebug() << "CMAC_Update failed.";
        CMAC_CTX_free(ctx);
        return result;
    }

    // Finalize CMAC calculation
    unsigned char mac[AES_BLOCK_SIZE];
    size_t macLength;
    if (CMAC_Final(ctx, mac, &macLength) != 1) {
    
    
        qDebug() << "CMAC_Final failed.";
        CMAC_CTX_free(ctx);
        return result;
    }
    // Convert the result to QByteArray
    result = QByteArray(reinterpret_cast<char*>(mac), macLength);
    // Free the CMAC context
    CMAC_CTX_free(ctx);
    QFileInfo fileInfo(filePath);
    QString newFilePath = fileInfo.path() + "/" + fileInfo.baseName() + ".security." + fileInfo.suffix();
    if (!QFile::copy(filePath, newFilePath)) {
    
    
            qDebug() << "Failed to create a copy of the original file:" << filePath;
    }
    QFile copiedFile(newFilePath);
    if (!copiedFile.open(QIODevice::Append)) {
    
    
        qDebug() << "Failed to open copied file for appending:" << newFilePath;
    }
    // Append the result to the copied file
    copiedFile.write(result);
    copiedFile.close();
    qDebug() << "CMAC result appended to the copied file and saved to:" << newFilePath;
    ui->textEdit->setText(result.toHex());
    QFileInfo fileInf(filePath);
       QString newFile = fileInf.path() + "/" + fileInf.baseName() + "_reversedData." + fileInf.suffix();
       QFile reversedDataFile(newFile);
       if (reversedDataFile.open(QIODevice::WriteOnly)) {
    
    
           reversedDataFile.write(reversedData);
           reversedDataFile.close();
           qDebug() << "Reversed data written to the new file:" << newFilePath;
       } else {
    
    
           qDebug() << "Failed to open the new file for writing:" << newFilePath;
       }
    return result;
}

PS: Looking for a big guy online who is familiar with encryption algorithms

Want to ask some questions

Supongo que te gusta

Origin blog.csdn.net/a1379292747/article/details/134424619
Recomendado
Clasificación