旧技術

SHA-1暗号文字列化

投稿日:

いちばん簡単なやつ。

とりあえず。
– 暗号にしたい文字列をSHA-1文字列化する
– 比較する
-暗号化して格納する
– 格納したのを復号化する。

SHA-1文字列化

String^ result = System::Web::Security::FormsAuthentication::HashPasswordForStoringInConfigFile(keydata, "sha1")->ToLower();

これだけ。

パスワード暗号化・復号化

まだ完全には原理が分かってないんだよなぁ。

まぁとりあえず、ここではパスワードをSHA-1化文字列にしている。
ソルト(salt)は分からなかったのでそのまま8バイトのままにしてみた。

参考。

-http://blogs.msdn.com/shawnfa/archive/2005/11/10/491431.aspx

ソース

#using <mscorlib.dll>
#using <System.Web.dll>
#using <System.Security.dll>
#using <mscorlib.dll>

using namespace System;
using namespace System::Security::Cryptography;
using namespace System::Text;
using namespace System::IO;

#define RESOURCEDATA L"89ede2f410ac0613d4b655bbfacfc81428c52f24"

/**
 * パスワード暗号化(AES用)(AES 128bit)
 * 入力 暗号対象文字列
 *      パスワード文字列
 * 出力 暗号後文字列(Base64)
 **/
String^ Encrypt(String^ encryptstr,String^ password) {
    String^ encryptedstr = nullptr;

    //8は8バイトのような気がする。
    Rfc2898DeriveBytes^ keyGenerator = gcnew Rfc2898DeriveBytes(password,8);
    Rijndael^ aes = Rijndael::Create();
    aes->IV = keyGenerator->GetBytes(aes->BlockSize / 8);
    aes->Key = keyGenerator->GetBytes(aes->KeySize / 8);

    /* Unicodeが微妙 */
    array<Byte>^ rawData = Encoding::Unicode->GetBytes(encryptstr);
    MemoryStream^ memoryStream = gcnew MemoryStream();
    CryptoStream^ cryptoStream = gcnew CryptoStream(memoryStream, aes->CreateEncryptor(), CryptoStreamMode::Write);

    /* ソルトをデータとして書き込む */
    memoryStream->Write(keyGenerator->Salt, 0, keyGenerator->Salt->Length);
    cryptoStream->Write(rawData, 0, rawData->Length);
    cryptoStream->Close();

    array<Byte>^ encrypted = memoryStream->ToArray();
    encryptedstr = Convert::ToBase64String(encrypted);

    Console::WriteLine("OK " + encryptstr);

    return encryptedstr;
}

/**
 * パスワード復号化
 * 入力 暗号対象文字列
 *      パスワード文字列
 * 出力 暗号後文字列(Base64)
 **/
String^ Decrypt(String^ encryptstr,String^ password) {
    String^ decryptstr = nullptr;

    array<Byte>^ rawData = Convert::FromBase64String(encryptstr);

    //ソルト(暗号するための種)を設定している。バイナリデータの最初に指定したから。
    array<Byte>^ salt = gcnew array<Byte>(8);
    for(int i = 0; i < salt->Length; i++) {
            salt[i] = rawData[i];
    }

    Rfc2898DeriveBytes^ keyGenerator = gcnew Rfc2898DeriveBytes(password,salt);
    Rijndael^ aes = Rijndael::Create();
    aes->IV = keyGenerator->GetBytes(aes->BlockSize / 8);
    aes->Key = keyGenerator->GetBytes(aes->KeySize / 8);

    MemoryStream^ memoryStream = gcnew MemoryStream();
    CryptoStream^ cryptoStream = gcnew CryptoStream(memoryStream, aes->CreateDecryptor(), CryptoStreamMode::Write);

    //ソルトの後からデータを取得している。
    cryptoStream->Write(rawData, 8, rawData->Length-8);
    cryptoStream->Close();

    array<Byte>^ decrypted = memoryStream->ToArray();
    decryptstr = Encoding::Unicode->GetString(decrypted);

    Console::WriteLine("OK " + decryptstr);

    return decryptstr;
}

int main(array<System::String ^> ^args)
{
    String^ keydata = "12345-xxxxx-xxxxx-xxxxx-6789x";
    //文字列からSHA1してBase64に
    String^ result = System::Web::Security::FormsAuthentication::HashPasswordForStoringInConfigFile(keydata, "sha1")->ToLower();
    Console::WriteLine(result);

    //次は比較。
    String^ results = gcnew String(RESOURCEDATA); 

    if ( result->CompareTo(results) == 0 ) {
        Console::WriteLine("比較OK");
    }

    //あとはライセンスの格納。面倒だからRESOURCEDATAで暗号化しとくか。
    //関数を想定。
    String^ encryptstr = Encrypt(keydata,results);

    Console::WriteLine("暗号前データ=A " + keydata);
    Console::WriteLine("パスワード " + results);
    Console::WriteLine("暗号後データ " + encryptstr);

    String^ decryptstr = Decrypt(encryptstr,results);

    Console::WriteLine("暗号前データ " + encryptstr);
    Console::WriteLine("パスワード " + results);
    Console::WriteLine("暗号後データ(=Aと一緒) " + decryptstr);

    return 0;
}

出力結果

89ede2f410ac0613d4b655bbfacfc81428c52f24
比較OK
OK 12345-xxxxx-xxxxx-xxxxx-6789x
暗号前データ=A 12345-xxxxx-xxxxx-xxxxx-6789x
パスワード 89ede2f410ac0613d4b655bbfacfc81428c52f24
暗号後データ OPrE7kiNeKvguGvjmmvy9kTsV33jStSz9Jrhya+I3yOQ7JAjBghc0RQPoHijlxj6xaR
cI6RLbxkS5y6SKNX91rksG4FZ6Se5
OK 12345-xxxxx-xxxxx-xxxxx-6789x
暗号前データ OPrE7kiNeKvguGvjmmvy9kTsV33jStSz9Jrhya+I3yOQ7JAjBghc0RQPoHijlxj6xaR
cI6RLbxkS5y6SKNX91rksG4FZ6Se5
パスワード 89ede2f410ac0613d4b655bbfacfc81428c52f24
暗号後データ(=Aと一緒) 12345-xxxxx-xxxxx-xxxxx-6789x

-旧技術

執筆者:

関連記事

新規プロジェクト参入時に考えること

派遣における労働条件 就業予定時間(変形労働時間やフレックスタイム制の適用を含む)残業の有無と量就業場所(交通ルート、オフィスの配置等)業務の継続予定期間 制服の有無 (背広かどうか)福利厚生施設の有 …