C#和Ruby之间的AES和SHA 512加密/解密

fnx2tebb  于 2023-06-05  发布在  Ruby
关注(0)|答案(1)|浏览(327)

加密和解密我的代码的过程与银行的过程不匹配。也就是说,当我使用我的代码加密和解密一切工作正常。但是,当我试图将我的代码加密的结果发送到银行时,他们回答我错误500,另一方面,解密过程中以银行为例,在结果的开头显示特殊字符。
我的ruby代码基于这个C# code
我的代码:

require 'openssl'
require 'base64'

class SecurityManager
  PASSWORD = 'example'.freeze
  CERT_PATH = Rails.root.join('config', 'documents', 'EXAMPLE_EMPRESA.pfx').to_s.freeze

  def self.encrypt(plain_text)
    return nil if plain_text.nil?

    bytes_to_be_encrypted = plain_text.encode('UTF-8')
    aux = get_thumbprint_from_certificate

    key = aux + PASSWORD
    password_bytes = key.encode('UTF-8')

    password_bytes = OpenSSL::Digest.new('SHA512').digest(password_bytes)

    bytes_encrypted = encrypt_internal(bytes_to_be_encrypted, password_bytes)

    Base64.strict_encode64(bytes_encrypted)
  end

  def self.decrypt(encrypted_text)
    return nil if encrypted_text.nil?

    bytes_to_be_decrypted = Base64.strict_decode64(encrypted_text)

    thumbprint = get_thumbprint_from_certificate
    key = thumbprint + PASSWORD
    password_bytes = key.encode('UTF-8')

    password_bytes = OpenSSL::Digest.new('SHA512').digest(password_bytes)

    bytes_decrypted = decrypt_internal(bytes_to_be_decrypted, password_bytes)

    bytes_decrypted.force_encoding('UTF-8')
  end

  def self.encrypt_internal(bytes_to_be_encrypted, password_bytes)
    salt_bytes = [1, 2, 3, 4, 5, 6, 7, 8].pack('C*')

    cipher = OpenSSL::Cipher.new('AES-256-CBC')
    cipher.encrypt

    key = OpenSSL::PKCS5.pbkdf2_hmac(password_bytes, salt_bytes, 1000, cipher.key_len, 'sha1')

    cipher.key = key[0, 32]
    cipher.iv = key[0, 16]

    cipher.update(bytes_to_be_encrypted) + cipher.final
  end

  def self.decrypt_internal(bytes_to_be_decrypted, password_bytes)
    salt_bytes = [1, 2, 3, 4, 5, 6, 7, 8].pack('C*')

    cipher = OpenSSL::Cipher.new('AES-256-CBC')
    cipher.decrypt

    key = OpenSSL::PKCS5.pbkdf2_hmac(password_bytes, salt_bytes, 1000, cipher.key_len, 'sha1')

    cipher.key = key[0, 32]
    cipher.iv = key[0, 16]

    cipher.update(bytes_to_be_decrypted) + cipher.final
  end

  def self.thumbprint_from_certificate
    pfx_data = File.read(CERT_PATH)
    pfx = OpenSSL::PKCS12.new(pfx_data, PASSWORD)
    cert = pfx.certificate
    OpenSSL::Digest::SHA1.new(cert.to_der).hexdigest
  end
end

加密示例:

MRehs7Hr5+hN5ug8fhpsIrmlXgqChPAs82lYUvIw1gVhSM56MjlWSk5JNP3UvqKsJw1Grb6C2Q5pKqvyKPiq2W8cr0ZAQBS2aqP0RSD/D4m2ID4oxZix4b5ZljPd2899

代码的结果

"\xBF\xF2\xF1\xC9}\xBC\xBF\x91U\xF9nn\f\xFA\xF6\xA8essage\":\"Los datos personales del usuario son incorrectas.\",\"body\":null}"

预期结果

"{\"message\":\"Los datos personales del usuario son incorrectas.\",\"body\":null}"

其他结果来自银行的另一个加密示例:

"\xBFݒ\x9A\u0012\xF7\xBD\x89P\xF7om\b\xB8\xAD\x8Cd\": 2295,\r\n    \"password\": \"example\",\r\n    \"documentNumber\": \"XXXXXXX\",\r\n    \"documentType\": \"Q\",\r\n    \"documentExtension\": \"LP\",\r\n    \"documentComplement\": \"\",\r\n    \"amount\": 0.3,\r\n    \"currency\": \"BOL\",\r\n    \"fundSource\": \"Ventas de tarjetas de regalo\",\r\n    \"fundDestination\": \"Comercios que realizaron las ventas\",\r\n    \"sourceAccount\": \"2011040905323\",\r\n    \"sourceCurrency\": \"BOL\",\r\n    \"description\": \"Pagos por ventas efectuadas\",\r\n    \"sendVouchers\": \"info@example.com\",\r\n    \"cismartApprovers\": [\r\n        {\r\n            \"idc\": \"04011574-Q-PO\",\r\n            \"type\": 1\r\n        }\r\n    ],\r\n    \"spreadsheet\": {\r\n        \"formProvidersPayments\": [\r\n            {\r\n                \"paymentType\": \"PROV\",\r\n                \"line\": 1,\r\n                \"accountNumber\": \"2011040905323\",\r\n                \"glossPayment\": \"Pago por ventas\",\r\n                \"amount\": 0.1,\r\n                \"documentType\": \"Q\",\r\n                \"documentNumber\": \"0280000\",\r\n                \"documentExtension\": \"\",\r\n                \"firstDetail\": \"detalle 1\",\r\n                \"secondDetail\": \"detalle 2\",\r\n                \"mail\": \"\"\r\n            }\r\n        ],\r\n        \"formAchPayments\": [\r\n            {\r\n                \"paymentType\": \"ACH\",\r\n                \"line\": 1,\r\n                \"accountNumber\": \"5555555555\",\r\n                \"titularName\": \"nombre de titular\",\r\n                \"firstLastName\": \"\",\r\n                \"secondLastName\": \"\",\r\n                \"amount\": 0.2,\r\n                \"branchOfficeId\": 201,\r\n                \"firstDetail\": \"detalle\",\r\n                \"mail\": \"\",\r\n                \"bankId\": \"8888\"\r\n            }\r\n        ],\r\n        \"formOddPayments\": [\r\n            {\r\n                \"paymentType\": \"ODD\",\r\n                \"line\": 1,\r\n                \"accountNumber\": \"cuentaAdebitar\",\r\n                \"titularName\": \"William\",\r\n                \"firstLastName\": \"Prueba\",\r\n                \"secondLastName\": \"Prueba\",\r\n                \"description\": \"pruebaDescripcion\",\r\n                \"glossPayment\": \"pruebaGlosa\",\r\n                \"amount\": 0.3,\r\n                \"documentType\": \"Q\",\r\n                \"documentNumber\": \"7894561\",\r\n                \"DocumentExtension\": \"LP\",\r\n                \"branchOfficeId\": 201,\r\n                \"firstDetail\": \"DET ODD\",\r\n                \"SecondDetail\": \"SEC ODD\",\r\n                \"mail\": \"example@examplecom\",\r\n                \"bankId\": \"8888\",\r\n                \"commission\": 0.1,\r\n                \"CommissionCurrency\": \"BOL\"\r\n            }\r\n        ]\r\n    }\r\n}"

正如您所看到的,特殊字符仅在开头。

vlju58qv

vlju58qv1#

非常感谢您抽出时间来帮助我。
特别提到topaco的分析。
更正代码:

def self.decrypt_internal(bytes_to_be_decrypted, password_bytes)
    salt_bytes = [1, 2, 3, 4, 5, 6, 7, 8].pack('C*')

    cipher = OpenSSL::Cipher.new('AES-256-CBC')
    cipher.decrypt

    key = OpenSSL::PKCS5.pbkdf2_hmac(password_bytes, salt_bytes, 1000, cipher.key_len + cipher.iv_len, 'sha1')

    cipher.key = key[0, 32]
    cipher.iv = key[32, 16]

    cipher.update(bytes_to_be_decrypted) + cipher.final
  end

加密看起来像这样:

def self.encrypt_internal(bytes_to_be_encrypted, password_bytes)
    salt_bytes = [1, 2, 3, 4, 5, 6, 7, 8].pack('C*')

    cipher = OpenSSL::Cipher.new('AES-256-CBC')
    cipher.encrypt

    key = OpenSSL::PKCS5.pbkdf2_hmac(password_bytes, salt_bytes, 1000, cipher.key_len + cipher.iv_len, 'sha1')

    cipher.key = key[0, 32]
    cipher.iv = key[32, 16]

    cipher.update(bytes_to_be_encrypted) + cipher.final
  end

相关问题