我正在编写一个将与 php 脚本(authentication.php?UserID=ClientsEmail@email.com&ClientsID=81E17)通信的应用程序,如果在 MySQL 数据库中找到客户端以及客户端的文件是什么,该脚本将通知应用程序可以下载。Internet 上的所有通信都将经过 AES-256 (CBC) 加密,并且主加密密钥将被硬编码到可执行文件中。通过重新编译 exe 并将其作为升级传递给所有客户端,该主密钥每年只会更改一次。因为这个键很少改变,所以我生成一个希望永远不会重复的初始化向量是至关重要的。
因为我的密文输出是 Base 64。我试图使 IV 尽可能统一,换句话说,让它看起来好像是密文输出的一部分。
所以我的第一个问题是下面的函数重复的可能性有多大。我确实创建了一个打开了计时器的测试应用程序,并循环了下面的函数,将其添加到数据库并检查它是否重复。测试应用程序运行了一夜,总共循环了 69369 次,没有重复。
// Generate a 16 bytes = 128 bits Initialization vector Used for AES-256
Function TfrmMain.GenerateIV:String;
Var
i,j : Integer;
Const
{Uppercase}
alpa_L : array[1..26] of string = ('a','b','c','d','e','f','g','h','i','j','k',
'l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z');
{Lowercase}
alpa_U : array[1..26] of string = ('A','B','C','D','E','F','G','H','I','J','K',
'L','M','N','O','P','Q','R','S','T','U','V',
'W','X','Y','Z');
{numeric}
Num : array[1..10] of string = ('0','1','2','3','4','5','6','7','8','9');
Begin
Result := '';
Randomize;
for i := 1 to 16 do //16 bytes = 128 bits AES=Fixed 128 Blocks
Begin
j := RandomRange(1, 4); //RandomRange - Delphi's help says inclusive but it is non-inclusive
case j of
1: Result := Result + alpa_L[RandomRange(1, 27)]; {alphabetic Uppercase}
2: Result := Result + alpa_U[RandomRange(1, 27)]; {alphabetic Lowercase}
3: Result := Result + Num[RandomRange(1, 11)] {numeric}
end;
end;
end;
说了这么多,我有另一个想法,我正在尝试整合。我的想法如下,而不是将主要加密密钥硬编码到可执行文件中。我的服务器将随机生成一个加密密钥,并将其不受保护地传递给我的应用程序。服务器和应用程序之间的所有通信都将使用该会话的此密钥进行加密,并且一旦下载了所有文件,会话就会关闭。
以上唯一的问题是,由于加密密钥被发送到该会话未受保护的应用程序,因此可以通过一些精明的方式查看应用程序和服务器正在通信的内容,并且黑客可以看到身份验证是如何完成的。一旦他/她知道这一点,就可以将应用程序重定向到他们的服务器以进行身份验证部分,然后照常继续。解决这个问题的唯一方法是保护这个密钥,但我又回到了“硬编码到可执行文件中”的问题
所以我的这个应用程序的第一个版本将把密钥硬编码到可执行文件中,直到我解决了上述问题。
不幸的是,服务器不支持(HTTPS)协议