このプログラムを作り始めた経緯
最近ずっとセーブデータの暗号化プログラムを考えてたんですが、単に暗号化するだけでもよかったんですが、それだと暗号の意味が破られた時にセーブデータ書き換えられるよなと思いました。
ただ、暗号破りしてクリアした人を暗号破りせず素直にやってる人がいじめをやるとかそういうこと始めたら嫌だなと思いました。なんせ考えた暗号化方法って結構シンプルだったので…。まあ逆にあんまり複雑にしても復号化も面倒だなと思ってたのでいいんですが。
そこで目をつけたのがWindowsのレジストリでした。
Windowsのレジストリは結構暗号のように複雑に文字列が組み合わさってるのでこれの中の何かを暗号化に使えないかなと思い、いろんなところを見てました。そうしたら
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
にS-1-5-21で始まる文字列のフォルダでした。
この中を見たら、ユーザープロファイルのフォルダがあり、「あ、これユーザーの識別に関わってるキーじゃないかな」と思いました。ただ、これをデータの暗号化に使うにはさすがに苦でした。そこで思いついたのが、「あ、これをファイル名にしてしまえばいいんじゃないか?」ということでした。
ただ、私のVAIOと家族で使ってるVAIOのレジストリを見比べたら、このキーはPC毎に違うことが分かり、取得のしようがないなと諦めてました。そもそも考えついた時はこの文字列の正体すら分からなかったので…。
調べてみたらこれがWindowsのユーザーのセキュリティ識別子(SID)であると分かり、それを取得するためのAPIもMicrosoftから提供されていたので、セーブデータにこれを使うかどうかは別として、早速このプログラムをまとめてみようと思い、作りました。
std::string GetSIDStringA(const std::string ComputerName, const std::string UserName) {
char sidBuf[256];
DWORD dwSidLen = 0, dwDomainLen = 256;
SID_NAME_USE snu;
LookupAccountNameA(ComputerName.c_str(), UserName.c_str(), NULL, &dwSidLen, sidBuf, &dwDomainLen, &snu);
PSID psid = (PSID)HeapAlloc(GetProcessHeap(), 0, dwSidLen);
if (0 == LookupAccountNameA(ComputerName.c_str(), UserName.c_str(), psid, &dwSidLen, sidBuf, &dwDomainLen, &snu))
throw std::runtime_error("Error in LookupAccountName Function");
LPSTR lpbuf;
if (0 == ConvertSidToStringSidA(psid, &lpbuf)) throw std::runtime_error("Error in ConvertSidToStringSid Function");
std::string s;
s.resize(std::strlen(lpbuf));
s = lpbuf;
return s;
}
std::wstring GetSIDStringW(const std::wstring ComputerName, const std::wstring UserName) {
wchar_t sidBuf[256];
DWORD dwSidLen = 0, dwDomainLen = 256;
SID_NAME_USE snu;
LookupAccountNameW(ComputerName.c_str(), UserName.c_str(), NULL, &dwSidLen, sidBuf, &dwDomainLen, &snu);
PSID psid = (PSID)HeapAlloc(GetProcessHeap(), 0, dwSidLen);
if (0 == LookupAccountNameW(ComputerName.c_str(), UserName.c_str(), psid, &dwSidLen, sidBuf, &dwDomainLen, &snu))
throw std::runtime_error("Error in LookupAccountName Function");
LPWSTR lpbuf;
if (0 == ConvertSidToStringSidW(psid, &lpbuf)) throw std::runtime_error("Error in ConvertSidToStringSid Function");
std::wstring s;
s.resize(std::wcslen(lpbuf));
s = lpbuf;
return s;
}
SIDを知ってる人なんて早々はいないはずなので、ファイル名とかにしておけばセーブデータとかたぶんバレづらいかも?