52 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			52 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| module Gitlab
 | |
|   module CryptoHelper
 | |
|     extend self
 | |
| 
 | |
|     AES256_GCM_OPTIONS = {
 | |
|       algorithm: 'aes-256-gcm'
 | |
|     }.freeze
 | |
| 
 | |
|     def sha256(value)
 | |
|       salt = Gitlab::Encryption::KeyProvider[:db_key_base_truncated].encryption_key.secret
 | |
|       ::Digest::SHA256.base64digest("#{value}#{salt}")
 | |
|     end
 | |
| 
 | |
|     def encryption_key
 | |
|       @encryption_key ||= Gitlab::Encryption::KeyProvider[:db_key_base_32].encryption_key
 | |
|     end
 | |
| 
 | |
|     def aes256_gcm_encrypt(value, nonce: nil)
 | |
|       encrypted_token = Encryptor.encrypt(
 | |
|         AES256_GCM_OPTIONS.merge(
 | |
|           value: value,
 | |
|           iv: nonce || Gitlab::Utils.ensure_utf8_size(encryption_key.secret, bytes: 12.bytes),
 | |
|           key: encryption_key.secret
 | |
|         )
 | |
|       )
 | |
|       Base64.strict_encode64(encrypted_token)
 | |
|     end
 | |
| 
 | |
|     def aes256_gcm_decrypt(value, nonce: nil)
 | |
|       return unless value
 | |
| 
 | |
|       encrypted_token = Base64.decode64(value)
 | |
|       keys = Gitlab::Encryption::KeyProvider[:db_key_base_32].decryption_keys
 | |
| 
 | |
|       # Try to decrypt with all keys, from oldest to newest
 | |
|       keys.each_with_index do |key, index|
 | |
|         return Encryptor.decrypt( # rubocop:disable Cop/AvoidReturnFromBlocks -- next doesn't work the same here
 | |
|           AES256_GCM_OPTIONS.merge(
 | |
|             value: encrypted_token,
 | |
|             key: key.secret,
 | |
|             iv: nonce || Gitlab::Utils.ensure_utf8_size(key.secret, bytes: 12.bytes)
 | |
|           )
 | |
|         )
 | |
|       rescue OpenSSL::Cipher::CipherError
 | |
|         raise if index == keys.length - 1
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 |