对称密码
来源:互联网 发布:慈溪行知职高地址全称 编辑:程序博客网 时间:2024/05/20 11:47
概念介绍
对称密码就是加密和解密使用同一个key
对称密码算法有很多,但是现在只有AES (Advanced Encryption Standard) 是最常用的,其它像 DES, 3DES 等都已淘汰
AES是一种块密码算法,块密码算法只能对固定长度的数据进行加密,例如:AES的块长度是128位,即16字节。AES算法将一个明文块加密生成一个密文块,密文快的长度跟明文块相等,都为16字节。
如果要加密的数据比16字节长,就要进行分块加密,然后将密文块组合成完整的密文。
分块加密并组合有多种方法,称为mode。主要模式有ecb, cbc, cfb, ofb, ctr 等,但是最常用的只有两种:即 cbc 和 ctr,其它都已淘汰
代码
为方便使用,下面对苹果平台提供的对称密码库做个封装
头文件:Aes.h
#ifndef Aes_h#define Aes_h#include <stdint.h>#include <vector>class Aes final {public: enum struct Mode { Cbc, Ctr, }; enum struct Operation { Encrypt, Decrypt, }; enum { KeySize128 = 16, KeySize192 = 24, KeySize256 = 32, };public: typedef std::vector<uint8_t> Data;public: static Data encrypt_cbc_128(const Data &data, const uint8_t (&key)[KeySize128], const uint8_t (&iv)[16]); static Data decrypt_cbc_128(const Data &data, const uint8_t (&key)[KeySize128], const uint8_t (&iv)[16]);public: ~Aes(); Aes(Operation op, Mode mode, const uint8_t (&key)[KeySize128], const uint8_t (&iv)[16]); Aes(Operation op, Mode mode, const uint8_t (&key)[KeySize192], const uint8_t (&iv)[16]); Aes(Operation op, Mode mode, const uint8_t (&key)[KeySize256], const uint8_t (&iv)[16]); Aes(Aes &&aes) noexcept; Aes &operator=(Aes &&aes) noexcept; Data update(const Data &data); Data final(); void reset();private: struct AesImpl *_impl = nullptr;};#endif /* Aes_h */
实现文件:Aes.cpp
#include "Aes.h"#include <CommonCrypto/CommonCryptor.h>#include <assert.h>struct AesImpl final {public: ~AesImpl() { CCCryptorRelease(_cryptor); } AesImpl(Aes::Operation op, Aes::Mode mode, const void *key, size_t keyLength, const void *iv) { CCCryptorCreateWithMode(_operation(op), _mode(mode), kCCAlgorithmAES, ccPKCS7Padding, iv, key, keyLength, nullptr, 0, 0, 0, &_cryptor); } Aes::Data update(const Aes::Data &data) { size_t len = CCCryptorGetOutputLength(_cryptor, data.size(), false); Aes::Data buf(len); size_t size = 0; CCCryptorUpdate(_cryptor, data.data(), data.size(), buf.data(), buf.size(), &size); return buf; } Aes::Data final() { Aes::Data buf(kCCBlockSizeAES128); size_t size = 0; CCCryptorFinal(_cryptor, buf.data(), buf.size(), &size); buf.resize(size); return buf; } void reset() { CCCryptorReset(_cryptor, nullptr); }private: constexpr CCOperation _operation(Aes::Operation op) const { switch (op) { case Aes::Operation::Encrypt: return kCCEncrypt; case Aes::Operation::Decrypt: return kCCDecrypt; } } constexpr CCMode _mode(Aes::Mode mode) const { switch (mode) { case Aes::Mode::Cbc: return kCCModeCBC; case Aes::Mode::Ctr: return kCCModeCTR; } }private: CCCryptorRef _cryptor = nullptr;};#pragma mark -Aes::~Aes(){ delete _impl;}Aes::Aes(Operation op, Mode mode, const uint8_t (&key)[KeySize128], const uint8_t (&iv)[16]) : _impl(new AesImpl(op, mode, key, KeySize128, iv)){}Aes::Aes(Operation op, Mode mode, const uint8_t (&key)[KeySize192], const uint8_t (&iv)[16]) : _impl(new AesImpl(op, mode, key, KeySize192, iv)){}Aes::Aes(Operation op, Mode mode, const uint8_t (&key)[KeySize256], const uint8_t (&iv)[16]) : _impl(new AesImpl(op, mode, key, KeySize256, iv)){}Aes::Aes(Aes &&aes) noexcept : _impl(aes._impl){ aes._impl = nullptr;}Aes &Aes::operator=(Aes &&aes) noexcept{ assert(&aes != this); delete _impl; _impl = aes._impl; aes._impl = nullptr; return *this;}Aes::Data Aes::update(const Data &data){ return _impl->update(data);}Aes::Data Aes::final(){ return _impl->final();}void Aes::reset(){ return _impl->reset();}Aes::Data Aes::encrypt_cbc_128(const Data &data, const uint8_t (&key)[KeySize128], const uint8_t (&iv)[16]){ Data buf; Aes aes(Operation::Encrypt, Mode::Cbc, key, iv); auto u = aes.update(data);; buf.insert(buf.end(), u.cbegin(), u.cend()); auto f = aes.final(); buf.insert(buf.end(), f.cbegin(), f.cend()); return buf;}Aes::Data Aes::decrypt_cbc_128(const Data &data, const uint8_t (&key)[KeySize128], const uint8_t (&iv)[16]){ Data buf; Aes aes(Operation::Decrypt, Mode::Cbc, key, iv); auto u = aes.update(data);; buf.insert(buf.end(), u.cbegin(), u.cend()); auto f = aes.final(); buf.insert(buf.end(), f.cbegin(), f.cend()); return buf;}
示例:main.cpp
#include <iostream>#include <stdio.h>#include <stdarg.h>#include <string>#include <vector>#include <algorithm>#include <numeric>#include "Aes.h"std::string format(const char *fmt, ...){ va_list ap; va_start(ap, fmt); int size = vsnprintf(nullptr, 0, fmt, ap) + 1; va_end(ap); char *buf = new char[size]; va_start(ap, fmt); vsnprintf(buf, size, fmt, ap); va_end(ap); std::string fs(buf, size-1); delete[] buf; return fs;}std::string toHexString(const Aes::Data &data){ std::vector<std::string> svec; std::transform(data.cbegin(), data.cend(), std::back_inserter(svec), [](auto byte) { return format("%02X", byte); }); return std::accumulate(svec.cbegin(), svec.cend(), std::string());}int main(){ const uint8_t key[16] = { 0xa5, 0xc0, 0xda, 0xb7, 0x87, 0x45, 0xc7, 0x37, 0x95, 0x07, 0x2C, 0x96, 0x67, 0xae, 0x28, 0xf1 }; const uint8_t iv[16] = { 0xdb, 0x32, 0x9a, 0x66, 0x09, 0x8b, 0x67, 0xf7, 0xb5, 0xa7, 0x9f, 0x38, 0x57, 0xb9, 0x25, 0x41 }; std::string msg = "hello, world"; Aes::Data data(msg.cbegin(), msg.cend()); auto enc = Aes::encrypt_cbc_128(data, key, iv); std::cout << toHexString(enc) << std::endl; auto dec = Aes::decrypt_cbc_128(enc, key, iv); std::cout << std::string(dec.cbegin(), dec.cend()) << std::endl;}
运行输出:
$ ./a.outBC0B8E8AF2458A300E08A350B48EE793hello, world
阅读全文
0 0
- 对称密码
- 对称密码
- 对称、非对称密码体制
- 对称密码&公钥密码
- 非对称密码
- 对称密码之DES
- 对称密码之AES
- 对称密码之PBE
- 对称密码体制
- 华为OJ--对称密码提取
- 对称密码的编程使用
- 对称密码获取(OJ)
- 非对称密码的基本原理
- 对称密码之3DES
- 非对称密码的简介
- 密码技术之对称加密
- SM2非对称密码算法
- 有关对称密码的几个思考
- python中的单例
- bzoj 1296 [SCOI2009]粉刷匠 (dp)
- 六、tensorflow之添加层。
- 和大于S的最小子数组-LintCode
- ACdream 1157 Segments(cdq分治)
- 对称密码
- android adapter控件及高级控件
- 深度学习所需的python-学习笔记4
- 安卓获取手机短信(Contentprovider)
- 最短路径—Dijkstra算法(C#)
- 无线自动轮播,获取网络上的图片+scrollView+listView 联动
- 74HC573芯片介绍
- js实现常见排序算法
- [工作流activiti]-01.基础篇