密码的加密

3

我已经成功地使用以下代码对输入的密码进行了简单的加密,然后在标签的标题中显示加密后的密码:

procedure TfrmLogin.edtAddPasswordClick(Sender: TObject);
var
  NormalPassword, EncryptedPassword: string;
  PasswordChar: Char;
  EncryptedCharValue: string;
  CharPtr: Integer;
  Ptr, n: Integer;
begin
  NormalPassword := Edit1.text;
  EncryptedPassword := '';
  for CharPtr := 1 to Length(NormalPassword) do
  begin
    PasswordChar := NormalPassword[CharPtr];
    EncryptedCharValue := IntToStr (Ord(PasswordChar) * 5 + 14);
    EncryptedPassword := EncryptedPassword + EncryptedCharValue;
    Label1.Caption := EncryptedPassword;
  end;
end;

问题在于我想要在点击另一个按钮时将label1.caption中显示的加密密码转换回其原始形式,但我无法弄清楚如何完成。有什么建议吗?


6
一般来说,密码是被哈希而不是加密的。并且你无法反向哈希。 - Oliver Charlesworth
1
该算法无法被反转。 - David Heffernan
1
Oli的原则是正确的,虽然我可以看出有些情况下您希望这是可逆的;例如,密码存储应用程序。 但在那种情况下,您可能希望使用更强的算法,并由用户选择密钥。 - Geoff
@DavidHeffernan,确实,我以为你是在说无法获取原始字符串 :) - RRUZ
@DavidHeffernan,你能解释一下为什么不同的字符串会产生相同的输出吗? - Geoff
显示剩余7条评论
5个回答

6

不要自己创建密码哈希(或加密)算法,尝试使用经过充分测试和可靠的算法,如SHA1、MD5等。

回到你的问题,将加密值转换为原始值,你需要反转你的算法,可以尝试这个示例。

var
  NormalPassword, EncryptedPassword: String;
  PasswordChar : char;
  EncryptedCharValue : String;
  CharPtr : Integer;
begin
  NormalPassword    :='';
  EncryptedPassword := Label1.Caption; //here is stored the encrypted password
  CharPtr := 1;
  while CharPtr< length(EncryptedPassword) do
    Begin
      EncryptedCharValue:=Copy(EncryptedPassword, CharPtr, 3);
      Inc(CharPtr, 3);
      PasswordChar     := Chr((StrToint(EncryptedCharValue)-14) div 5);
      NormalPassword  :=NormalPassword+ PasswordChar;
    end;
    Label2.Caption := NormalPassword; 
end;

chr(198) 映射到一个4位数值,所以这段代码无法工作。而且还有一些输入映射到2位数值。 - David Heffernan
2
CopyInc - RRUZ
2
copyinc - Andreas Rejbrand
@user1277240 因为在 #18 和 #197 之间的每个字符的 ord 值乘以 5 再加上 14 都会产生一个由 3 位数字组成的值。 - RRUZ
2
@DavidHeffernan 给我几分钟,我现在正在使用一部旧浏览器的 Android 手机,编辑问题非常困难 ;) - RRUZ
显示剩余7条评论

4
我知道这是一份作业,目的是得到反转代码,其他人提供了太多细节,但我需要把这个作为答案给出,因为它的概念对于笔记来说太重要了:
如果你真的在谈论密码,那么你必须让密码可逆。用户期望他们的密码是安全的、不可逆的。
如果你想这么做的原因是因为你想在用户忘记密码时发送密码给他们,那么答案是不要这样做
当一个人失去或忘记他们的密码时,你应该将密码提供给他们,因为这证明它是不安全的。相反,在确保他们是注册用户(通过电子邮件地址或其他方式)之后,允许他们输入自己选择的新密码,这才是正确的做法。

2
如果你决定按照描述的方式去做,你可以通过更改以下这行代码使它可逆转:
EncryptedCharValue := IntToStr (Ord(PasswordChar) * 5 + 14);

to

EncryptedCharValue := format('%.4d', [Ord(PasswordChar) * 5 + 14]);

这将使您稍后能够将字符串分成四个字符块,减去14,除以5,然后将其转换回字符。 尽管如此,我仍然坚持我的早期评论-如果您实际上需要可逆安全性的用例,请使用更强的算法,例如在这个问题中讨论的算法。 [编辑:四个字符显然更加健壮]

+1 这种方法实际上会得到一个可逆的算法。 - David Heffernan

1

你的函数是一个非常简单的哈希算法,无法被反转。以可逆的方式存储密码是没有意义的,因为它不会增加任何额外的安全层次(除非你使用基于非对称加密的复杂方案)。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接