双向密钥加密/哈希算法

时间:2009-08-25 20:02:00

标签: algorithm encryption hash

我对这类事情没有经验,所以我甚至不确定关键字(因此标题)。 基本上我需要一个双向函数

encrypt(w,x,y) = z

decrypt(z) = w, x, y

Where w = integer 
      x = string (username)
      y = unix timestamp 

和z =是一个8位数字(可能包括字母,规格还没有。)

我希望z不易猜测且易于验证。速度不是巨大的关注点,安全性也不是。跟踪一对一关系是主要要求。 任何资源或方向都将受到赞赏。

修改

感谢您的回答,学到了很多东西。因此,为了澄清,8个字符是唯一的硬性要求,以及链接W< - >的能力。 Z.用户名(Y)和时间戳(Z)将被认为是锦上添花。

我想在数学上做这个,而不是做一些数据库查找,如果可能的话。

如果我今晚必须完成这个,我可以找到一个合适的哈希算法并使用查找表。我只是想扩大我对这类事物的理解,看看我是否可以用数学方法做到这一点。

7 个答案:

答案 0 :(得分:17)

加密与散列

这是一个加密问题,因为需要恢复原始信息。加密哈希的质量取决于反转哈希和恢复原始信息的难度,因此散列不适用于此。

要执行加密,需要一些关键材料。有许多加密算法,但它们分为两大类:对称和非对称。

应用

此处的申请尚不清楚。但是,如果您正在“加密”某些信息并将其发送到某个地方,然后将其取回并使用它执行某些操作,则对称加密是可行的方法。例如,假设您要在某个HTML链接中包含的参数中对应用程序中的用户名,IP地址和某些标识符进行编码。当用户单击该链接时,该参数将传递回您的应用程序并对其进行解码以恢复原始信息。这非常适合对称加密,因为发件人和收件人是同一方,密钥交换是无操作。

背景

在对称加密中,发件人和收件人需要知道相同的密钥,但要对其他人保密。举个简单的例子,两个人可以亲自见面,并决定密码。稍后,他们可以使用该密码将他们的电子邮件彼此保密。但是,任何无意中听到密码交换的人都可以监视他们;交换必须通过安全通道进行...但如果您有一个安全通道,则无需更换新密码。

在非对称加密中,每一方都创建一对密钥。一个是公开的,可以免费分发给任何想要发送私人消息的人。另一个是私人的。只有邮件收件人知道该私钥。

对称加密的一大优势是速度快。所有设计良好的协议都使用对称算法来加密大量数据。缺点是安全地交换密钥可能很困难 - 如果你不能在一个安全的地方“虚拟地或身体地”“见面”以便同意密码呢?

由于公钥可以自由共享,因此两个人可以通过不安全的渠道交换私人消息,而无需事先就密钥达成一致。但是,非对称加密要慢得多,因此通常用于加密对称密钥或对对称密码执行“密钥协商”。 SSL和大多数加密协议都经过握手,其中非对称加密用于设置对称密钥,用于保护对话的其余部分。

答案 1 :(得分:11)

您只需要使用私钥加密(w,x,y)的序列化。使用相同的私钥对其进行解密。

在任何情况下,z的大小都不能像你那样简单地限制,因为它取决于序列化的大小(因为它需要是双向的,你可以做的压缩有一定的约束,取决于熵)。

你并不是在寻找一个哈希函数,因为它显然会丢失一些信息而你却无法反转它。

编辑:由于z的大小是硬限制,因此需要将输入限制为8个字节,并选择使用64位(或更少)块大小的加密技术。 BlowfishTriple DES使用64位块,但请记住,这些算法没有像AES那样受到同样的审查。

如果你想要一些非常简单且非常不安全的东西,只需使用密钥xor输入。

答案 2 :(得分:3)

你可能不会。

假设w是32位,x支持至少8个不区分大小写的ASCII字符,所以至少37位,y是32位(达到2038,31位甚至不能让你到现在)。

所以,这总共至少有101位数据。您正试图将其存储在8位数字中。在数学上不可能从较大的集合到较小的集合创建可逆函数,因此每个“数字”需要存储超过12.5位。

当然,如果你超过8个字符,或者你的字符是16位unicode,那么你至少有机会。

答案 3 :(得分:1)

根据定义,哈希只是一种方式,一旦哈希,很难再次获得原始值。

对于双向加密,我会查看.net已经使用TripleDESCryptoServiceProvider创建的TripleDES。

A fairly straight forward implementation article.

修改

下面已经提到过,您不能将大量信息塞入一个小的加密值中。但是,对于许多(并非所有)情况,这正是Bit Masks要解决的问题。

答案 4 :(得分:1)

加密或不加密,我认为不可能将这么多信息打包成8位数字,以便您能够再次获取它。

整数是4个字节。假设您的用户名限制为8个字符,并且该字符是字节。然后时间戳至少是另外4个字节。那是16个字节。在十六进制中,将采用32位数字。 Base36或其他东西会更少,但它不会接近8。

答案 5 :(得分:1)

让我们正确化你的问题,以便更好地研究它。

k成为可能键集K的键,(w, x, y)来自集合I的一段信息,我们需要加密。让我们将“加密消息”的集合定义为A 8 ,其中A是字母表,我们从中提取字符到我们的加密消息(A = {0,1,...,9, a,b,...,z,...},根据您的说明,正如您所说的那样。)

我们定义了两个函数:

crypt: I * K --> A^8.
decrypt A^8 * K --> I

这里的问题是加密消息的集合A ^ 8的大小可能小于信息片段(w,x,y)的大小。如果是这样的话,除非我们尝试不同的东西,否则根本无法实现你想要的东西......

假设只有您(或您的服务器或服务器上的应用程序)必须能够从z计算(w,x,y)。也就是说,您可以将z发送给某人,而您并不关心他们无法解密它。

在这种情况下,您可以使用服务器上的数据库。您将使用众所周知的算法来隐藏信息,而不是生成随机数z。您定义表:

Id: char[8]
CryptedInformation: byte[]

然后,您将在Id列上存储z,并在相应列上存储加密信息。

当您需要解密信息时,有人会给您z,加密信息的索引,然后您可以继续解密。

但是,如果这对你有用,你可能甚至不需要加密信息,你可以有一个表:

Id: char[8]
Integer: int
Username: char[]
Timestamp: DateTime

使用相同的方法,无需加密任何内容。

例如,这可以应用于订阅过程中的“电子邮件验证系统”。您通过邮件发送给用户的链接将包含z

希望这有帮助。

答案 6 :(得分:0)

我无法判断您是否尝试将其设置为存储密码的方式,但如果您这样做,则不应使用双向哈希函数。

如果你真的想要做你所描述的,你应该只连接字符串和时间戳(用下划线或其他东西填充额外的空格)。获取结果字符串,将其转换为ASCII或UTF-8等,并找到其模数小于10 ^ 8的最大素数。