代码之家  ›  专栏  ›  技术社区  ›  Philip

在没有外部宝石的Ruby中进行简单加密

  •  20
  • Philip  · 技术社区  · 15 年前

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

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

    有什么建议吗?我不想使用外部宝石。

    菲利普

    8 回复  |  直到 8 年前
        1
  •  42
  •   Graham Slick    10 年前

    您可以使用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"
    

    但是中间形式不适合印刷


    考虑到您认为如果中间形式的长度相同就更好了,您可以使用一个字符到另一个字符的简单映射。

    请理解这不安全

    你可以 容易地 蛮力的钥匙,但它似乎符合你的要求。

    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"
    
        2
  •  16
  •   nicholaides    9 年前

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

    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
    
        3
  •  7
  •   Jignesh Gohel    10 年前

    对于基本的编码/解码目的,我想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中使用编码字符串的情况下使用版本方法。

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

        4
  •  3
  •   Nakilon earlonrails    12 年前

    我可以向您推荐uuencode和uuedecode utils 您可以使用Wuth Standart Ruby函数包:

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

    (来自哈尔富尔顿红宝石之路的样品)

        5
  •  3
  •   Prashanth Sams    8 年前

    加密和解密的可选方法

    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)
    
        6
  •  2
  •   Paul Rubel    15 年前

    你真的想相信用户会给你正确的价值吗?如果你相信客户机给你的信息,并且用户知道你的加密方案,你将使用他们提供的数据。听起来是个很糟糕的主意。

    我不明白为什么你不想给他们一个数据库的密钥,这个数据库可以将随机数(可能带有一些纠错属性)映射到优惠券折扣上。这样你就可以控制最终的结果。他们提供给你一把钥匙,你查找相关联的优惠券并应用优惠券。通过这种方式,您只使用自己的数据,如果您想删除优惠券,那么它都在服务器端。

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

        7
  •  2
  •   Philip    15 年前

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

    注意,你需要计算a在2^n上的倒数,你可以用扩展的gcd计算wolfram alpha的倒数。

        8
  •  0
  •   user2373148    9 年前

    您可以在此注册表中使用Ruby检查所有不同的加密/解密方法: https://gist.github.com/iufuenza/183a45c601a5c157a5372c5f1cfb9e3e

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

    推荐文章