在博客上实施 ID 加密不会产生相同的输出

发布于 2024-11-09 09:44:25 字数 1985 浏览 0 评论 0原文

我看到这篇博客文章,其中描述了他们如何加密他们的 ID。出于教育和娱乐目的,我决定尝试一下。但我不太明白。

正如这篇博文中所述,我是基础36 对 3DES 加密的 64 位填充值进行编码,并保持结果字符串的长度为 25 个字符。如何在不使用流密码的情况下获得 13 个字符(如该网站声称的那样)——该博客声称使用 3DES 分组密码。

这是我正在使用的代码:

require 'openssl'

SECRET_KEY = "secret"
ENCRYPTION_ALGO = "DES-EDE3-CBC"

def base36encode(s)
  s.unpack('H*')[0].to_i(16).to_s 36
end

def base36decode(s36)
  [s36.to_i(36).to_s(16)].pack 'H*'
end

def num_to_bits(n, bit_count=64)
  #Array.new(bit_count) { |i| (n)[i] }.reverse!
  sprintf('%064b', n).split("")
end

def bits_to_string(bits)
  [bits.join("")].pack("B*")
end

def num_to_binstring(n, bit_count=64)
  bits_to_string(num_to_bits(n, bit_count))
end

def binstring_to_num(str)
  #elements = str.unpack("N*")
  #(elements[0] << 32) | elements[1]
  #
  ans = 0
  str.each_byte do |i|
    ans = ans * 256 + i
  end

  ans
end

def encrypt(message, password)
  cipher = OpenSSL::Cipher::Cipher.new(ENCRYPTION_ALGO)
  cipher.encrypt
  cipher.pkcs5_keyivgen(password)
  ciphertext = cipher.update(message)
  ciphertext << cipher.final
end

def decrypt(message, password)
  cipher = OpenSSL::Cipher::Cipher.new(ENCRYPTION_ALGO)
  cipher.decrypt
  cipher.pkcs5_keyivgen(password)
  decryptedtext = cipher.update(message)
  decryptedtext << cipher.final
end

id = 12345678
puts "Encrypting: \"#{id}\""

num_string = num_to_binstring(id)
encrypted = encrypt(num_string, SECRET_KEY)
encoded = base36encode(encrypted).upcase
puts "Encrypted and encoded to: \"#{encoded}\" that's size is: #{encoded.length}\n"

decoded = base36decode(encoded.downcase)
decrypted = decrypt(decoded, SECRET_KEY)
string_num = binstring_to_num(decrypted)
puts "Decoded and decrypted to: \"#{string_num}\""

# ---- OUTPUT ---
# Encrypting: "12345678"
# Encrypted and encoded to: "49OMDVRHHMM24DVMODQU4X7JY" that's size is: 25
# Decoded and decrypted to: "12345678"

I came across this blog post which describes how they encrypt their ID's. For educational and entertainment purposes, I decided to try this out. I can't quite get it, though.

As described in this blog post, I'm base 36 encoding the 3DES encrypted 64 bit padded value and keep getting the resulting string to be 25 characters long. How is it possible to get 13 characters, like the site claims, without using some stream cipher -- the blog claims to use a 3DES block cipher.

Here's the code I'm using:

require 'openssl'

SECRET_KEY = "secret"
ENCRYPTION_ALGO = "DES-EDE3-CBC"

def base36encode(s)
  s.unpack('H*')[0].to_i(16).to_s 36
end

def base36decode(s36)
  [s36.to_i(36).to_s(16)].pack 'H*'
end

def num_to_bits(n, bit_count=64)
  #Array.new(bit_count) { |i| (n)[i] }.reverse!
  sprintf('%064b', n).split("")
end

def bits_to_string(bits)
  [bits.join("")].pack("B*")
end

def num_to_binstring(n, bit_count=64)
  bits_to_string(num_to_bits(n, bit_count))
end

def binstring_to_num(str)
  #elements = str.unpack("N*")
  #(elements[0] << 32) | elements[1]
  #
  ans = 0
  str.each_byte do |i|
    ans = ans * 256 + i
  end

  ans
end

def encrypt(message, password)
  cipher = OpenSSL::Cipher::Cipher.new(ENCRYPTION_ALGO)
  cipher.encrypt
  cipher.pkcs5_keyivgen(password)
  ciphertext = cipher.update(message)
  ciphertext << cipher.final
end

def decrypt(message, password)
  cipher = OpenSSL::Cipher::Cipher.new(ENCRYPTION_ALGO)
  cipher.decrypt
  cipher.pkcs5_keyivgen(password)
  decryptedtext = cipher.update(message)
  decryptedtext << cipher.final
end

id = 12345678
puts "Encrypting: \"#{id}\""

num_string = num_to_binstring(id)
encrypted = encrypt(num_string, SECRET_KEY)
encoded = base36encode(encrypted).upcase
puts "Encrypted and encoded to: \"#{encoded}\" that's size is: #{encoded.length}\n"

decoded = base36decode(encoded.downcase)
decrypted = decrypt(decoded, SECRET_KEY)
string_num = binstring_to_num(decrypted)
puts "Decoded and decrypted to: \"#{string_num}\""

# ---- OUTPUT ---
# Encrypting: "12345678"
# Encrypted and encoded to: "49OMDVRHHMM24DVMODQU4X7JY" that's size is: 25
# Decoded and decrypted to: "12345678"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

波浪屿的海角声 2024-11-16 09:44:25

在进行 Base36 编码之前,加密输出的大小是多少?我的猜测是,您的代码正在 CBC 模式下加密(假设您的代码提到了 pkcs5),并且您正在获取 IV 和密文,总共 16 个字节。我从博客文章中推断,作者使用的是 ECB 模式,您可能会认为“原始”3DES,这在大多数情况下通常是错误的,但在这里似乎是合理的。

What size is the output of the encryption before you base36 encode? My guess is that your code is encrypting in CBC mode (given that your code mentions pkcs5) and you're getting the IV and ciphertext out, a total of 16 bytes. I infer from the blog post that the author is using ECB mode, what you might think of as "raw" 3DES, which is usually wrong for most situations but seems plausible here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文