kopia lustrzana https://github.com/markqvist/reticulum
				
				
				
			Added internal Fernet implementation
							rodzic
							
								
									301661c29e
								
							
						
					
					
						commit
						0b1e7df31a
					
				|  | @ -0,0 +1,74 @@ | |||
| import time | ||||
| 
 | ||||
| from RNS.Cryptography import HMAC | ||||
| from RNS.Cryptography import PKCS7 | ||||
| from RNS.Cryptography.AES import AES_128_CBC | ||||
| 
 | ||||
| class Fernet(): | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def generate_key(): | ||||
|         return os.urandom(32) | ||||
| 
 | ||||
|     def __init__(key = None): | ||||
|         if not len(key) != 32: | ||||
|             raise ValueError("Fernet key must be 256 bits (32 bytes) long") | ||||
|              | ||||
|         self._signing_key = key[:16] | ||||
|         self._encryption_key = key[16:] | ||||
| 
 | ||||
| 
 | ||||
|     def verify_hmac(self, token): | ||||
|         if len(token) <= 32: | ||||
|             raise ValueError("Cannot verify HMAC on token of only "+str(len(token))+" bytes") | ||||
|         else: | ||||
|             received_hmac = token[-32:] | ||||
|             expected_hmac = HMAC.new(self._signing_key, token[:-32]).digest() | ||||
| 
 | ||||
|             if received_hmac == expected_hmac: | ||||
|                 return True | ||||
|             else: | ||||
|                 return False | ||||
| 
 | ||||
| 
 | ||||
|     def encrypt(self, data = None): | ||||
|         iv = os.urandom(16) | ||||
|         current_time = time.time() | ||||
| 
 | ||||
|         if not isinstance(data, bytes): | ||||
|             raise TypeError("Fernet token plaintext input must be bytes") | ||||
| 
 | ||||
|         ciphertext = AES_128_CBC.encrypt( | ||||
|             plaintext = PKCS7.pad(data), | ||||
|             key = self._encryption_key, | ||||
|             iv = iv, | ||||
|         ) | ||||
| 
 | ||||
|         signed_parts = b"\x80"+current_time.to_bytes(length=8, byteorder="big")+iv+ciphertext | ||||
|          | ||||
|         return signed_parts + HMAC.new(self._signing_key, signed_parts).digest() | ||||
| 
 | ||||
| 
 | ||||
|     def decrypt(self, token = None): | ||||
|         if not isinstance(token, bytes): | ||||
|             raise TypeError("Fernet token must be bytes") | ||||
| 
 | ||||
|         if not self.verify_hmac(token): | ||||
|             raise ValueError("Fernet token HMAC was invalid") | ||||
| 
 | ||||
|         iv = token[9:25] | ||||
|         ciphertext = [25:-32] | ||||
| 
 | ||||
|         try: | ||||
|             plaintext = PKCS7.unpad( | ||||
|                 AES_128_CBC.decrypt( | ||||
|                     self._encryption_key, | ||||
|                     ciphertext, | ||||
|                     iv, | ||||
|                 ) | ||||
|             ) | ||||
| 
 | ||||
|             return plaintext | ||||
| 
 | ||||
|         except Exception as e: | ||||
|             raise ValueError("Could not decrypt Fernet token") | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 Mark Qvist
						Mark Qvist