Base64 形式の文字列を
暗号化するアルゴリズムを思いついたため
今回は紹介しようと思います。
役に立つかは不明ですが
面白いアルゴリズムだとは思いますので
知見を得るというよりは
このアルゴリズムを楽しむ事を目的として
閲覧して頂けると嬉しいです。
暗号化・複合化するコード
public class MyEncrypter {
public static string MyEncrypt(string rootBase64String)
{
string thinking = CreateMyKey();
StringBuilder create = new();
create.Append(rootBase64String[0]);
for (int i = 1; i < rootBase64String.Length; i++)
{
if (rootBase64String[i] == '=')
{
create.Append("=");
continue;
}
int index = thinking.IndexOf("" + create[i - 1]) + thinking.IndexOf("" + rootBase64String[i]);
if (thinking.Length - 1 < index)
{
index -= thinking.Length;
}
create.Append(thinking[index]);
}
return create.ToString();
}
public static string MyDecrypt(string encryptedBase64String)
{
string thinking = CreateMyKey();
StringBuilder create = new();
create.Append(encryptedBase64String[0]);
for (int i = 1; i < encryptedBase64String.Length; i++)
{
if (encryptedBase64String[i] == '=')
{
create.Append("=");
continue;
}
int index = thinking.IndexOf("" + encryptedBase64String[i]) - thinking.IndexOf("" + encryptedBase64String[i - 1]);
if (index < 0)
{
index += thinking.Length;
}
create.Append(thinking[index]);
}
return create.ToString();
}
//Base64 の文字を 64 文字・重複無しで並べた文字列を返します。
private static string CreateMyKey()
{
System.Text.StringBuilder thinking = new("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
int nowCulc = 13241;
for (int i = 0; i < 20000; i++)
{
int target1 = Math.Abs(nowCulc % 64);
nowCulc *= 63;
nowCulc += 15731;
int target2 = Math.Abs(nowCulc % 64);
nowCulc *= 59;
nowCulc += 34721;
char oneTime = thinking[target1];
thinking[target1] = thinking[target2];
thinking[target2] = oneTime;
}
return thinking.ToString();
}
}
MyEncrypter.MyEncrypt(rootBase64String);
で暗号化します。
MyEncrypter.MyDecrypt(encryptedBase64String);
で暗号化した文字列を複合化します。
string rootString = "o3Dgc+d";
string encriptString = MyEncrypter.MyEncrypt(rootString);
string resultString = MyEncrypter.MyDecrypt(encriptString);
bool isTheSame = rootString == resultString; // true
と言った使い方です。
最初の 1 文字は同じで
2 文字目以降を
前の文字との差分で保存しています。
thinking 変数は Base64 の文字を
重複なく 64 文字入れて下さい。
順序はバラバラの方が
セキュリティが高いです。
thinking 変数が
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
と仮定すると
B の次が E ならば
CDE と 3 文字進んでるため
thinking[3] を保存しています。
b の次が h ならば
cdefgh と 6 文字進んでいるため
thinking[6] を保存しています。
MyEncrypt メソッドと
MyDecrypt メソッドの
thinking 変数は
同じ内容にする必要があります。
thinking 変数の内容は
AES のキーと同じように
隠すようにして下さい。
上記の例で言うと
int nowCulc = 13241;
の 13241 を隠すイメージです。
nowCulc += 15731;
等の数値部分も隠せると
もっと良いです。
任意の文字列を key にする場合は
下記のようなコードを
作成する必要があると思います。
下記のコードは
ハッシュコードの生成アルゴリズムに
自信がないため
確実に正常に動作するか分かりません。
文字列を一意の int に
100% 変換できる自信が無いのです。
具体的には文字コードなどの影響で
nowCulc *= (int)one;
の部分がぶれる気がしています。
下記のコードは参考程度に捉えて下さい。
// こちらは CreateMyKey メソッドが正常に動作するか不明のため、参考程度に捉えて下さい。
public class MyEncrypter2 {
public static string MyEncrypt(string rootBase64String, string key)
{
string thinking = CreateMyKey(key);
StringBuilder create = new();
create.Append(rootBase64String[0]);
for (int i = 1; i < rootBase64String.Length; i++)
{
int index = thinking.IndexOf("" + create[i - 1]) + thinking.IndexOf("" + rootBase64String[i]);
if (thinking.Length - 1 < index)
{
index -= thinking.Length;
}
create.Append(thinking[index]);
}
return create.ToString();
}
public static string MyDecrypt(string encryptedBase64String, string key)
{
string thinking = CreateMyKey(key);
StringBuilder create = new();
create.Append(encryptedBase64String[0]);
for (int i = 1; i < encryptedBase64String.Length; i++)
{
if (encryptedBase64String[i] == '=')
{
continue;
}
int index = thinking.IndexOf("" + encryptedBase64String[i]) - thinking.IndexOf("" + encryptedBase64String[i - 1]);
if (index < 0)
{
index += thinking.Length;
}
create.Append(thinking[index]);
}
return create.ToString();
}
private static string CreateMyKey(string key)
{
System.Text.StringBuilder thinking = new("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
int nowCulc = 1;
foreach (char one in key)
{
nowCulc *= (int)one;
nowCulc += 17321;
}
for (int i = 0; i < 20000; i++)
{
int target1 = Math.Abs(nowCulc % 64);
nowCulc *= 63;
nowCulc += 15731;
int target2 = Math.Abs(nowCulc % 64);
nowCulc *= 61;
nowCulc += 34721;
char oneTime = thinking[target1];
thinking[target1] = thinking[target2];
thinking[target2] = oneTime;
}
return thinking.ToString();
}
}
以上 Base64 形式の文字列を
同じ Base64 に暗号化する
アルゴリズムを紹介しました。
byte 配列は
Convert.ToBase64String メソッドで
Base64 に変換できるため
使える機会自体はあると思っています。
数値を Base64 として見るならば
数値も Base64 に暗号化できると言えます。その場合は
数値を Base64 に圧縮するアルゴリズム で
圧縮してから暗号化する方法もあります。
このアルゴリズムは
このサイト で試す事ができます。
よろしければ試してみて下さい。
コードを読んで
面白いと感じて頂いたならば
非常に嬉しいです。
皆さんがこの記事を楽しめますように。
閲覧ありがとうございました。