Ruby中的简单加密,无需外部gem

我需要对一些文本字符串进行简单加密。 我想创建优惠券代码并使它们看起来很酷,因此随后创建的代码应该看起来非常不同。 (除了看起来很酷,猜测代码也不容易。)但我希望能够再次解密它们。 因此算法必须是可逆的。

我已经尝试了一些移动位的东西,所以它们看起来有点随机。 但是两个后续代码(只有一点不同)当然看起来非常相似。

有什么建议? 我想在不使用外部gem的情况下这样做。

菲利普

您可以使用OpenSSL :: Cypher

# for more info, see http://ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/Cipher.html require 'openssl' require 'digest/sha1' # create the cipher for encrypting cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc") cipher.encrypt # you will need to store these for later, in order to decrypt your data key = Digest::SHA1.hexdigest("yourpass") iv = cipher.random_iv # load them into the cipher cipher.key = key cipher.iv = iv # encrypt the message encrypted = cipher.update('This is a secure message, meet at the clock-tower at dawn.') encrypted << cipher.final puts "encrypted: #{encrypted}\n" # now we create a sipher for decrypting cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc") cipher.decrypt cipher.key = key cipher.iv = iv # and decrypt it decrypted = cipher.update(encrypted) decrypted << cipher.final puts "decrypted: #{decrypted}\n" 

但是中间forms不适合印刷


如果您认为如果中间forms长度相同会很好,您可能只使用一个char到另一个char的简单映射。

请理解这不安全

您可以轻松地强行关键,但它似乎与您的要求一致。

 class Cipher def initialize(shuffled) normal = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a + [' '] @map = normal.zip(shuffled).inject(:encrypt => {} , :decrypt => {}) do |hash,(a,b)| hash[:encrypt][a] = b hash[:decrypt][b] = a hash end end def encrypt(str) str.split(//).map { |char| @map[:encrypt][char] }.join end def decrypt(str) str.split(//).map { |char| @map[:decrypt][char] }.join end end # pass the shuffled version to the cipher cipher = Cipher.new ["K", "D", "w", "X", "H", "3", "e", "1", "S", "B", "g", "a", "y", "v", "I", "6", "u", "W", "C", "0", "9", "b", "z", "T", "A", "q", "U", "4", "O", "o", "E", "N", "r", "n", "m", "d", "k", "x", "P", "t", "R", "s", "J", "L", "f", "h", "Z", "j", "Y", "5", "7", "l", "p", "c", "2", "8", "M", "V", "G", "i", " ", "Q", "F"] msg = "howdy pardner" crypted = cipher.encrypt msg crypted # => "1IzXAF6KWXvHW" decrypted = cipher.decrypt crypted decrypted # => "howdy pardner" 

如果您不需要真正的加密,则可以使用简单的密码。 (当您不需要安全性或加密短随机/一次性字符串时,可以使用此方法。)

 ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" #generated with ALPHABET.split('').shuffle.join ENCODING = "MOhqm0PnycUZeLdK8YvDCgNfb7FJtiHT52BrxoAkas9RWlXpEujSGI64VzQ31w" def encode(text) text.tr(ALPHABET, ENCODING) end def decode(text) text.tr(ENCODING, ALPHABET) end 

对于基本的编码/解码目的,我想ruby的内置Base64库可以很方便:

 2.2.1 :001 > require 'base64' => true 2.2.1 :002 > str = "abc@example.com" => "abc@example.com" 2.2.1 :003 > Base64.encode64(str) => "YWJjQGV4YW1wbGUuY29t\n" 

如果要在url中使用编码字符串,它还具有urlsafe版本方法。

参考: http : //ruby-doc.org/stdlib-2.3.0/libdoc/base64/rdoc/Base64.html

我可以推荐你uuencode和uudecode utils你可以使用它们wuth standart ruby​​function包:

 str = "\007\007\002\abcde" new_string = [str].pack("u") original = new_string.unpack("u") 

(来自Hal Fulton的Ruby Way的样本)

您真的想要信任用户给您正确的价值吗? 如果您信任客户端回馈的内容并且用户确定您的加密方案,那么您将使用他们提供的数据。 这听起来是一个非常糟糕的主意。

我不清楚为什么你不想给他们一个密钥到一个数据库,该数据库将随机数(可能带有一些纠错属性)映射到优惠券折扣。 这样你就可以控制最终的结果了。 他们为您提供钥匙,您查找相关的优惠券并申请优惠券。 通过这种方式,您只使用自己的数据,如果要删除优惠券,则只需在服务器端进行。

如果保留所有密钥代码,您还可以检查新代码是否与以前发布的代码不同。

我想最简单的方法是* x + b(mod 2 ^ n)

请注意,您需要计算on 2 ^ n的倒数,您可以使用扩展GCD计算Wolfram Alpha。

加密和解密的可选方法

 gem 'activesupport' require 'active_support' key = SecureRandom.random_bytes(32) crypt = ActiveSupport::MessageEncryptor.new(key) encrypted_data = crypt.encrypt_and_sign("your password") password = crypt.decrypt_and_verify(encrypted_data) 

您可以在此要点中使用ruby检查所有不同的加密/解密方式: https : //gist.github.com/iufuenza/183a45c601a5c157a5372c5f1cfb9e3e

如果你不想使用gem,我会完全推荐Openssl作为最安全的,它也很容易实现,因为它有非常好的Ruby支持。