sirve - Cifrado simple en Ruby sin gemas externas.
ruby web (8)
¿Realmente quieres confiar en que el usuario te devuelva el valor correcto? Si confía en lo que el cliente le devuelve y el usuario descubre su esquema de cifrado, utilizará los datos que proporcione. Eso suena como una muy mala idea.
No tengo claro por qué no quiere darles una clave en una base de datos que asigna números aleatorios, tal vez con algunas propiedades de corrección de errores, a los descuentos de cupones. De esa manera usted tiene el control del resultado final. Le proporcionan una clave, usted busca el cupón asociado y aplica el cupón. De esta manera, solo está utilizando sus propios datos y si desea eliminar un cupón, todo está en el lado del servidor.
Si conserva todos los códigos clave, también puede verificar que los códigos nuevos sean diferentes de los que se lanzaron anteriormente.
Necesito un cifrado simple para algunas cadenas de texto. Quiero crear códigos de cupón y hacer que se vean geniales para que el código creado posteriormente tenga un aspecto muy diferente. (Y además de verse bien, no debería ser fácil adivinar un código). Pero quiero poder descifrarlos de nuevo. Entonces el algoritmo debe ser reversible.
Siempre he intentado algunas cosas con movimientos de bits para que parezcan un poco aleatorios. Pero, por supuesto, dos códigos posteriores (solo un bit diferente) parecen muy similares.
¿Alguna sugerencia? Me gustaría hacer eso sin usar gemas externas.
Felipe
Método opcional de cifrado y descifrado.
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)
Para propósitos básicos de codificación / decodificación, supongo que la biblioteca incorporada Base64 de ruby puede ser útil:
2.2.1 :001 > require ''base64''
=> true
2.2.1 :002 > str = "[email protected]"
=> "[email protected]"
2.2.1 :003 > Base64.encode64(str)
=> "YWJjQGV4YW1wbGUuY29t/n"
También tiene los métodos de la versión urlsafe en caso de que las cadenas codificadas se usen en las urls.
Referencia: http://ruby-doc.org/stdlib-2.3.0/libdoc/base64/rdoc/Base64.html
Podrías usar 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"
Pero la forma intermedia no se presta bien a la impresión.
Teniendo en cuenta que sería bueno que la forma intermedia tuviera la misma longitud, podría usar un mapa simple de un personaje a otro.
POR FAVOR ENTIENDA QUE ESTO NO ES SEGURO
Puede fácilmente forzar la clave, pero parece ser congruente con sus requisitos.
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"
Puede verificar todas las diferentes formas de cifrado / descifrado usando ruby en esta lista: https://gist.github.com/iufuenza/183a45c601a5c157a5372c5f1cfb9e3e
Si no desea utilizar una gema, recomendaría totalmente Openssl como la más segura, que también es muy fácil de implementar ya que tiene un muy buen soporte de Ruby.
Puedo recomendarte uuencode y uudecode utils, puedes usarlos con el paquete de funciones de ruby standart:
str = "/007/007/002/abcde"
new_string = [str].pack("u")
original = new_string.unpack("u")
(muestra de Ruby Way de Hal Fulton)
Si no necesita un cifrado real, puede utilizar un cifrado simple. (Esto se puede usar cuando no se necesita seguridad, o para cifrar cadenas aleatorias / puntuales cortas).
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
Supongo que la forma más sencilla es a * x + b (mod 2 ^ n)
Tenga en cuenta que necesita calcular el inverso de a en 2 ^ n, puede hacerlo con Wolfram Alpha usando GCD extendido.