c++ builder XE4, 10.2 Tokyo > String > 暗号化


(追記 2017/08/30): 「復号化」から「復号」に訂正しました。

動作確認
C++ Builder XE4
Rad Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)

文字列の暗号化(と復号)を行いたい。

参考 http://kenkou-engineer.seesaa.net/category/530724-1.html

上記ではSHA1による暗号化をしているようだ。

上記のページから取得できるファイルのコードをXE4向けかつ関数化したのが以下。


#define KEY_LENGTH_128  0x00800000  //128 bit

static AnsiString Encrypt(AnsiString srcStr, AnsiString password)
{
    char buf[100];
    unsigned long len;

    strcpy(buf, AnsiString(srcStr).c_str());
    len = strlen(buf);

    //Prepare CSP
    HCRYPTPROV hProv;
    if (CryptAcquireContext(&hProv, NULL,
        MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == false)
    {
//      ShowMessage("Error: CryptAcquireContext()");
        return L"";
    }

    //Create hash
    HCRYPTHASH hHash;
    if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash) == false)
    {
//      ShowMessage("Error: CryptCreateHash()");
        return L"";
    }

    //Create hash data
//  AnsiString password = L"myPassword";
    if (CryptHashData(hHash, password.c_str(), password.Length(), 0) == false)
    {
//      ShowMessage("Error: CryptHashData()");
        return L"";
    }

    //Create derive key
    HCRYPTKEY hKey;
    if (CryptDeriveKey(hProv, CALG_RC4, hHash, KEY_LENGTH_128, &hKey) == false)

    {
//      ShowMessage("Error: CryptDeriveKey()");
        return L"";
    }

    //Encode
    if (CryptEncrypt(hKey, 0, true, 0, buf, &len, len) == false)
    {
//      ShowMessage("Error: CryptEncrypt()");
        return L"";
    }

    CryptDestroyHash(hHash);
    CryptDestroyKey(hKey);
    CryptReleaseContext(hProv, 0);

    return AnsiString(buf);
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    AnsiString sample = L"1234567";

    AnsiString res = Encrypt(sample, "password1");

    int nop=1;

}

resには暗号化された文字列が入っている。

パスワード("password1")を隠しておくことで、復号されることを防げるのだろう。