2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Base64 形式の文字列を暗号化するアルゴリズム

Last updated at Posted at 2024-11-04

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 に圧縮するアルゴリズム
圧縮してから暗号化する方法もあります。

このアルゴリズムは
このサイト で試す事ができます。
よろしければ試してみて下さい。

コードを読んで
面白いと感じて頂いたならば
非常に嬉しいです。

皆さんがこの記事を楽しめますように。
閲覧ありがとうございました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?