C++ による RC4(Arcfour) 暗号化
「ARCFOUR Algorithm」を C++ に移植したので紹介します.
以下に実装する関数 encrypt_rc4/decrypt_rc4 を用いればバイト列(std::vector
RC4 については「RC4」をご覧下さい.
それでは以下に私の実装を示します.
rc4.hpp
#ifndef RC4_HPP_20100912_ #define RC4_HPP_20100912_ #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include <vector> namespace algorithm { void encrypt_rc4(const std::vector<unsigned char>& src, const std::vector<unsigned char>& key, std::vector<unsigned char>& dst); void decrypt_rc4(const std::vector<unsigned char>& src, const std::vector<unsigned char>& key, std::vector<unsigned char>& dst); } #endif
rc4.cpp
#include <algorithm> #include <numeric> #include "rc4.hpp" namespace { class arcfour_context { public: explicit arcfour_context(const std::vector<unsigned char>& key) : x_(0), y_(0) { unsigned int state_index = 0; unsigned int key_index = 0; std::iota(&state_[0], &state_[256], 0); for (int counter = 0; counter < 256; ++counter) { state_index = (state_index + key[key_index] + state_[counter]) & 0xFF; (std::swap)(state_[state_index], state_[counter]); if (++key_index >= key.size()) { key_index = 0; } } } unsigned char operator()() { unsigned int x = (x_ + 1 ) & 0xFF; unsigned int y = (y_ + state_[x]) & 0xFF; x_ = x; y_ = y; (std::swap)(state_[x], state_[y]); return state_[(state_[x] + state_[y]) & 0xFF]; } private: unsigned int x_; unsigned int y_; unsigned char state_[256]; }; } void algorithm::encrypt_rc4(const std::vector<unsigned char>& src, const std::vector<unsigned char>& key, std::vector<unsigned char>& dst) { arcfour_context context(key); std::vector<unsigned char> cdst; for (std::size_t i = 0; i < src.size(); ++i) { cdst.push_back(src[i] ^ context()); } dst = std::move(cdst); } void algorithm::decrypt_rc4(const std::vector<unsigned char>& src, const std::vector<unsigned char>& key, std::vector<unsigned char>& dst) { encrypt_rc4(src, key, dst); }
rc4.cpp に RC4 暗号化/復号化をする関数 encrypt_rc4/decrypt_rc4 を実装しました.rc4.cpp をプロジェクトに加え(他のソースコードと一緒にコンパイル),rc4.hpp を include することにより encrypt_rc4/decrypt_rc4 が使用可能になります.
以下のテストコードで encrypt_rc4/decrypt_rc4 の動作を確認できます.
test.cpp
#include <cassert> #include "rc4.hpp" int main() { std::vector<unsigned char> key; key.push_back(0x61); key.push_back(0x8a); key.push_back(0x63); key.push_back(0xd2); key.push_back(0xfb); std::vector<unsigned char> plain; plain.push_back(0xdc); plain.push_back(0xee); plain.push_back(0x4c); plain.push_back(0xf9); plain.push_back(0x2c); std::vector<unsigned char> cipher, dst; algorithm::encrypt_rc4(plain, key, cipher); // plain を key で暗号化 algorithm::decrypt_rc4(cipher, key, dst); // 暗号化した cipher を key で復号化 assert(plain.size() == dst.size()); for (std::size_t i = 0; i < plain.size(); ++i) { assert(plain[i] == dst[i]); } return 0; }
以上です.
非常に単純な記事ですが,少しでもお役に立てると幸いです.