Files
dtic-DIIAA/scripts/seguridad/secret_box.rb
T

92 lines
2.5 KiB
Ruby
Executable File

#!/usr/bin/env ruby
# frozen_string_literal: true
require 'openssl'
require 'base64'
require 'json'
class SecretBox
ALGORITHM = 'aes-256-gcm'.freeze
def initialize(master_key_content)
# Generar una clave de 32 bytes usando SHA256 sobre el contenido del master_key
@key = Digest::SHA256.digest(master_key_content.strip)
end
def encrypt(plaintext)
cipher = OpenSSL::Cipher.new(ALGORITHM)
cipher.encrypt
cipher.key = @key
iv = cipher.random_iv
ciphertext = cipher.update(plaintext.to_s) + cipher.final
auth_tag = cipher.auth_tag
# Base64 encodear las 3 partes para un JSON
payload = {
iv: Base64.strict_encode64(iv),
tag: Base64.strict_encode64(auth_tag),
data: Base64.strict_encode64(ciphertext)
}
Base64.strict_encode64(payload.to_json)
end
def decrypt(encrypted_payload)
parsed_payload = JSON.parse(Base64.strict_decode64(encrypted_payload), symbolize_names: true)
cipher = OpenSSL::Cipher.new(ALGORITHM)
cipher.decrypt
cipher.key = @key
cipher.iv = Base64.strict_decode64(parsed_payload[:iv])
cipher.auth_tag = Base64.strict_decode64(parsed_payload[:tag])
cipher.update(Base64.strict_decode64(parsed_payload[:data])) + cipher.final
rescue => e
raise "Error al desencriptar. Clave incorrecta o payload dañado. Detalles: #{e.message}"
end
end
if __FILE__ == $0
action = ARGV[0]
unless ['encrypt', 'decrypt'].include?(action)
puts "Uso:"
puts " ruby #{$0} encrypt <texto_plano>"
puts " ruby #{$0} decrypt <texto_encriptado>"
exit 1
end
text = ARGV[1]
if text.nil? || text.empty?
puts "Por favor, proporciona el texto a #{action}."
puts "Ejemplo:"
puts " ruby #{$0} encrypt \"MiSuperPassword\""
exit 1
end
# Buscar el archivo .master.key en el root del proyecto
key_path = File.join(File.expand_path('../..', __dir__), '.master.key')
unless File.exist?(key_path)
require 'securerandom'
File.write(key_path, SecureRandom.hex(32))
puts "⚠️ ATENCIÓN: Se ha creado una nueva clave maestra en '#{key_path}'"
puts " Asegúrate de NO subir este archivo a ningún repositorio (ya está cubierto por **/*.key en .gitignore)."
puts " Cualquiera que tenga este archivo podrá desencriptar los textos.\n\n"
end
box = SecretBox.new(File.read(key_path))
begin
if action == 'encrypt'
puts box.encrypt(text)
else
puts box.decrypt(text)
end
rescue => e
puts "Error: #{e.message}"
exit 1
end
end