AES 암호/복호 C/C++ 기능 구현
프로그래밍???/C/C++2015. 5. 6. 15:29
일년에 열번도 사용하지 않을 서버를 개발하고 있다.
중요한 건 나름 다양한 기술이 포함되어 있다는 것이다.
TCP/IP는 기본... 해당 서버쪽에서는 Health 체크도 했으면 싶어한다.
AES 암호화가 기본이기도 하다.
암호화를 잘 모르지만 나름 잘 정리된 싸이트와 라이브러리를 찾았다.
덕분에 매우 잘 쓰고 있다.
출처는 AES 암호/복호 C/C++ 기능 구현 이다.
아래의 내용은 해당 출처 내용의 복사본이다.
------------------------------------------------------------------------------------------------
AES 암호/복호 C/C++ 기능 구현
요즘 암호화가 필요해서 언어별로 AES 알고리즘을 가지고 암/복호화 하는 라이브러리를 개발하고 있습니다. 저와 같이 필요한 분들이 있을 것 같아 공유해 드립니다.
1. Cryptopp(Crypto++) 다운로드
- Cryptopp 홈피 : http://cryptopp.sourceforge.net/
- 다운로드 : http://sourceforge.net/project/showfiles.php?group_id=6152&package_id=6210
2. Cryptopp(Crypto++) 컴파일
- 다운 받은 파일을 압축 vna
- make;make install(make 만 한다음 libcryptopp.a, cryptest.exe 나오면 성공
- 원하는 libcryptopp.a 파일과 .h파일을 include디렉토리에 카피
3. AES 암호화/복호화 샘플 예제
- 앞서 등록한 포스트인 Flex 소스와 상호 암/복호가 가능하게 구현함
- key, iv를 활용하며 암호 문자열은 base64 인코딩함
- 추후 Java, ASP, PHP, C#도 공개할 예정
- 아래 결과를 여기서 암호문을 디코딩해보세요. 정상적으로 복호화됩니다.
1. Cryptopp(Crypto++) 다운로드
- Cryptopp 홈피 : http://cryptopp.sourceforge.net/
- 다운로드 : http://sourceforge.net/project/showfiles.php?group_id=6152&package_id=6210
2. Cryptopp(Crypto++) 컴파일
- 다운 받은 파일을 압축 vna
- make;make install(make 만 한다음 libcryptopp.a, cryptest.exe 나오면 성공
- 원하는 libcryptopp.a 파일과 .h파일을 include디렉토리에 카피
3. AES 암호화/복호화 샘플 예제
- 앞서 등록한 포스트인 Flex 소스와 상호 암/복호가 가능하게 구현함
- key, iv를 활용하며 암호 문자열은 base64 인코딩함
- 추후 Java, ASP, PHP, C#도 공개할 예정
#include <iostream>4. 실행 결과
#include <iomanip>
#include "cryptopp/cryptlib.h"
#include "cryptopp/modes.h"
#include "cryptopp/aes.h"
#include "cryptopp/filters.h"
#include "cryptopp/base64.h"
void hex2byte(const char *in, uint len, byte *out)
{
for (uint i = 0; i < len; i+=2) {
char c0 = in[i+0];
char c1 = in[i+1];
byte c = (
((c0 & 0x40 ? (c0 & 0x20 ? c0-0x57 : c0-0x37) : c0-0x30)<<4) |
((c1 & 0x40 ? (c1 & 0x20 ? c1-0x57 : c1-0x37) : c1-0x30))
);
out[i/2] = c;
}
}
int main(int argc, char* argv[]) {
//
// 키 할당
//
byte key[CryptoPP::AES::DEFAULT_KEYLENGTH];
memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH );
char* rawKey="f4150d4a1ac5708c29e437749045a39a";
hex2byte(rawKey, strlen(rawKey), key);
// IV 할당
byte iv[CryptoPP::AES::BLOCKSIZE];
memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE );
char* rawIv="86afc43868fea6abd40fbf6d5ed50905";
hex2byte(rawIv, strlen(rawIv), iv);
//
// 평문 할당
//
std::string plaintext = "http://mimul.com/pebble/default";
std::string ciphertext;
std::string base64encodedciphertext;
std::string decryptedtext;
std::string base64decryptedciphertext;
//
// 평문 출력
//
std::cout << "Plain Text (" << plaintext.size() <<
" bytes)" << std::endl;
std::cout << plaintext;
std::cout << std::endl << std::endl;
unsigned int plainTextLength = plaintext.length();
//
// AES 암호화 수행
//
CryptoPP::AES::Encryption
aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Encryption
cbcEncryption(aesEncryption, iv);
CryptoPP::StreamTransformationFilter
stfEncryptor(cbcEncryption, new CryptoPP::StringSink( ciphertext));
stfEncryptor.Put(reinterpret_cast<const unsigned char*>
(plaintext.c_str()), plainTextLength + 1);
stfEncryptor.MessageEnd();
//
// Base64 인코딩
//
CryptoPP::StringSource(ciphertext, true,
new CryptoPP::Base64Encoder(
new CryptoPP::StringSink(base64encodedciphertext)
) // Base64Encoder
); // StringSource
//
// Base64 인코딩 문자열 출력
//
std::cout << "Cipher Text (" << base64encodedciphertext.size()
<< " bytes)" << std::endl;
std::cout << "cipher : " << base64encodedciphertext << std::endl;
std::cout << std::endl << std::endl;
//
// Base64 디코딩
//
CryptoPP::StringSource(base64encodedciphertext, true,
new CryptoPP::Base64Decoder(
new CryptoPP::StringSink( base64decryptedciphertext)
) // Base64Encoder
); // StringSource
//
// AES 복호화
//
CryptoPP::AES::Decryption aesDecryption(key,
CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption
cbcDecryption(aesDecryption, iv );
CryptoPP::StreamTransformationFilter
stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decryptedtext));
stfDecryptor.Put( reinterpret_cast<const unsigned char*>
(base64decryptedciphertext.c_str()), base64decryptedciphertext.size());
stfDecryptor.MessageEnd();
//
// 복호화 문자열 출력
//
std::cout << "Decrypted Text: " << std::endl;
std::cout << decryptedtext;
std::cout << std::endl << std::endl;
return 0;
}
- 아래 결과를 여기서 암호문을 디코딩해보세요. 정상적으로 복호화됩니다.
Plain Text (31 bytes)
http://mimul.com/pebble/default
Cipher Text (65 bytes)
cipher :
TrP74bYahMS3MRB0zbP9HEitaqVMsfWh/pmpygYE9iA3JN4p5tyMejSf9u2GBS/9
Decrypted Text:
http://mimul.com/pebble/default
Re: AES 암호/복호 C/C++ 기능 구현
정말 많은 도움을 받았습니다.
다만, 약간의 수정이 필요할 듯 하여 코멘트를 남깁니다.
1. AES 과정 중
As is
stfEncryptor.Put(reinterpret_cast<const unsigned char*> (plaintext.c_str()), plainTextLength + 1);
To be
stfEncryptor.Put(reinterpret_cast<const unsigned char*> (plaintext.c_str()), plainTextLength);
2. Base64 과정 중
As is
new CryptoPP::StringSink(base64encodedciphertext)
To be
new CryptoPP::StringSink(base64encodedciphertext),false
다만, 약간의 수정이 필요할 듯 하여 코멘트를 남깁니다.
1. AES 과정 중
As is
stfEncryptor.Put(reinterpret_cast<const unsigned char*> (plaintext.c_str()), plainTextLength + 1);
To be
stfEncryptor.Put(reinterpret_cast<const unsigned char*> (plaintext.c_str()), plainTextLength);
2. Base64 과정 중
As is
new CryptoPP::StringSink(base64encodedciphertext)
To be
new CryptoPP::StringSink(base64encodedciphertext),false
'프로그래밍??? > C/C++' 카테고리의 다른 글
Creating STL Containers in Shared Memory (0) | 2015.07.10 |
---|---|
공유 메모리에 STL Container를 올리려고 하게 된 연유 (0) | 2015.07.10 |
AES의 block mode 관련 사항 (0) | 2015.05.08 |
multi thread에서 Mutex 사용시 에러... (0) | 2015.03.04 |
Producer/Consumer 큐 구현하기(std::vector와 Template를 함께 사용하기) (4) | 2015.02.24 |