【问题标题】:How to truncate a SHA1 hashed string into a 32 bit string如何将 SHA1 散列字符串截断为 32 位字符串
【发布时间】:2017-05-01 06:08:58
【问题描述】:

我想创建一个可以用作加密密钥的 32 位字符串。此字符串/键应源自纯文本字符串,例如:

'I am a string'

我的方法首先是散列它:

hashed_string = Digest::SHA1.hexdigest('I am a string') # => 'bd82fb0e81ee9f15f5929e0564093bc9f8015f1d'

然后只使用前 32 个字符:

hashed_string[0..31] # => 'bd82fb0e81ee9f15f5929e0564093bc9'

但是,我觉得必须有更好的方法,我不确定我是否会冒 2 个输入字符串产生相似键的风险。

什么是更好的方法?我看到this post 涉及截断,但在那里找不到吸引我的答案。

【问题讨论】:

  • gem pbkdf2 在您的情况下可能很有用 - 因为通常使用此类函数从密码短语派生密钥
  • 您似乎对位与字节有些混淆。 SHA1 哈希是 160 位。 hexdigest 返回这些位的 hexadecimal 表示。每个十六进制数字代表 4 位,因此当您取前 32 个字符时,您将得到 32 × 4 = 128 位。无论如何,是的,肯定有更好的方法——但首先我们必须知道你要解决什么问题。您想生成“加密密钥”,但目的是什么?你在加密什么,你是如何加密的?为什么是 32 位(very 是加密密钥的缩写)?
  • 换个问题怎么样? 32 bit string32 characters length string 是两个不同的东西。
  • 此外,无论您对原始字符串做什么,它都不会改变它是弱密码的事实。它的熵已经少于 32 位。见xkcd.com/936

标签: ruby encryption sha1 truncate truncation


【解决方案1】:

如果你想要一个包含 32 位的(弱)密码的字符串:

Digest::SHA1.digest('I am a string').unpack('B32').first
#=> "10111101100000101111101100001110"

同样的信息量也可以用8个十六进制数字显示:

Digest::SHA1.hexdigest('I am a string')[0,8]
#=> "bd82fb0e"

或 4 个 ascii 字符:

Digest::SHA1.digest('I am a string')[0,4]
#=> "\xBD\x82\xFB\x0E"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 2014-05-01
    • 2011-01-10
    • 2012-12-04
    • 2012-01-29
    • 2011-02-16
    相关资源
    最近更新 更多