密码学(二):对称加密和AES

对称加密与AES详解
本文深入探讨了对称加密的基本原理,强调了其在密钥生成、处理成本和硬件实现方面的优势。同时,详细介绍了高级加密标准(AES)作为对称加密的一种,包括其背景、安全性提升、加密速度优势及在各种协议中的广泛应用。

对称加密(或对称密钥加密)使用相同的密钥用于加密和解密:
在这里插入图片描述
对称密钥加密很有价值,有如下原因:

  • 为这些密码生成一个秘钥相对容易。
  • 就他们所能提供的保护水平而言,秘钥往往要小得多。
  • 这些算法的处理成本相对较低。

因此,实现对称加密(特别是使用硬件)可能非常有效,因为加密和解密不会导致任何显著的时间延迟。对称加密还提供了一定程度的身份验证,因为用一个对称密钥加密的数据不能用任何其他对称密钥解密。因此,只要对称密钥由使用它加密通信的双方保密,任何一方都可以确保它正在与另一方通信。
使用对称密钥,你可以与另一个受信任的参与者交换密钥。你可以确信在参与者之间交换的任何消息(这些消息是用特定密钥加密的)只能由拥有该密钥的其他参与者解密。这样,秘钥就必须对每个参与者保密。因此,这些密钥也称为秘钥密码。如果其他人发现了密钥,则会影响机密性和身份验证。
对称加密的主要缺点是交换密钥,因为任何交换都必须保留密钥的隐私。这通常意味着密匙必须用另一个密匙加密,并且接收方必须已经拥有解密加密密匙所需的密匙。

AES

AESAdvanced Encryption Standard,高级加密标准))是美国政府为保护机密信息而选择的对称分组密码,在全世界的软件和硬件中实施以加密敏感数据。
美国国家标准与技术研究院(NIST)于1997年开始开发AES,当时它宣布需要一种数据加密标准(DES)的后继算法,该算法开始变得容易受到暴力攻击。2003年6月,美国政府宣布AES可用于保护机密信息,并很快成为保护机密信息的默认加密算法,以及NSA批准的首个公开访问和开放密码的绝密信息。美国国家安全局选择AES作为其信息保障理事会用于保护国家安全系统的加密算法之一。
AES包括三种分组密码:AES-128AES-192AES-256。每个密码分别使用128 位,192位和256位的加密密钥以128 位的块加密和解密数据。AES比其前身DES3DES更安全,因为算法更强大并且使用更长的密钥长度。它还支持比DES3DES更快的加密,使其成为需要低延迟或高吞吐量的软件应用程序,固件和硬件的理想选择,例如防火墙和路由器。它用于许多协议,如安全套接字层(SSL)/传输层安全性(TLS),所以可以在大多数需要加密功能的现代应用程序和设备中看到它的应用。

加密和解密:OpenSSL命令行

要使用带有OpenSSLAES加密明文,请使用enc命令。以下命令将提示输入密码,加密名为un_encrypted.data的文件,输出到encrypted.data。我们将在此示例中使用密码12345

openssl enc -aes-256-cbc -in un_encrypted.data -out encrypted.data

以下命令将提示输入密码,解密名为encrypted.data的文件,输出到un_encrypted.data。我们将在此示例中使用与加密相同的密码12345

openssl enc -d -aes-256-cbc -in encrypted.data -out un_encrypted.data

使用OpenSSL API加密和解密

我们使用如下Openssl C语言API进行AESaes-cbc-128,aes-cbc-192,aes-cbc-256)加密/解密,我们的目标是:

  • 生成一个随机密钥
  • 生成一个随机IV
  • 加密一个包含X字符的常量数据块,然后解密相同的数据
  • 使用十六进制输出原始的、加密的和解密的数据
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>

// a simple hex-print routine. could be modified to print 16 bytes-per-line
static void hex_print(const void* pv, size_t len)
{
    const unsigned char * p = (const unsigned char*)pv;
    if (NULL == pv)
        printf("NULL");
    else
    {
        size_t i = 0;
        for (; i<len;++i)
            printf("%02X ", *p++);
    }
    printf("\n");
}

// main entrypoint
int main(int argc, char **argv)
{
    int keylength;
    printf("Give a key length [only 128 or 192 or 256!]:\n");
    scanf("%d", &keylength);

    /* generate a key with a given length */
    unsigned char aes_key[keylength/8];
    memset(aes_key, 0, keylength/8);
    if (!RAND_bytes(aes_key, keylength/8))
        exit(-1);

    size_t inputslength = 0;
    printf("Give an input's length:\n");
    scanf("%lu", &inputslength);

    /* generate input with a given length */
    unsigned char aes_input[inputslength];
    memset(aes_input, 'X', inputslength);

    /* init vector */
    unsigned char iv_enc[AES_BLOCK_SIZE], iv_dec[AES_BLOCK_SIZE];
    RAND_bytes(iv_enc, AES_BLOCK_SIZE);
    memcpy(iv_dec, iv_enc, AES_BLOCK_SIZE);

    // buffers for encryption and decryption
    const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
    unsigned char enc_out[encslength];
    unsigned char dec_out[inputslength];
    memset(enc_out, 0, sizeof(enc_out));
    memset(dec_out, 0, sizeof(dec_out));

    // so i can do with this aes-cbc-128 aes-cbc-192 aes-cbc-256
    AES_KEY enc_key, dec_key;
    AES_set_encrypt_key(aes_key, keylength, &enc_key);
    AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT);

    AES_set_decrypt_key(aes_key, keylength, &dec_key);
    AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT);

    printf("original:\t");
    hex_print(aes_input, sizeof(aes_input));

    printf("encrypt:\t");
    hex_print(enc_out, sizeof(enc_out));

    printf("decrypt:\t");
    hex_print(dec_out, sizeof(dec_out));

    return 0;
}

需要注意的地方包括:

  • 适当的密钥缓冲区大小
  • 适当的输出加密缓冲区大小:必须是块大小倍数,如果原始源缓冲区是精确的块大小倍数,则仍需要一个完整的填充块。
  • 相同的秘钥和IV用于加密和解密。

下面是测试结果:

$ gcc openssl_aes.c -o openssl_aes -lssl -lcrypto

$ ./openssl_aes
Give a key length [only 128 or 192 or 256!]:
256
Give an input's length:
20
original:       58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 
encrypt:        E0 6E 33 9A 35 E0 62 B9 B2 25 9F 44 E0 2E E3 F5 B3 DE 6C C7 FA 32 2C DC B7 C2 44 FA 64 58 BC 4C 
decrypt:        58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值