| 
						
						
						
					 | 
					 | 
					@ -1,10 +1,13 @@ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import 'dart:convert'; | 
					 | 
					 | 
					 | 
					import 'dart:convert'; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import 'dart:typed_data'; | 
					 | 
					 | 
					 | 
					import 'dart:typed_data'; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					import 'package:logging/logging.dart'; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import 'package:crypto/crypto.dart'; | 
					 | 
					 | 
					 | 
					import 'package:crypto/crypto.dart'; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import 'package:cryptography/cryptography.dart' as cryptography; | 
					 | 
					 | 
					 | 
					import 'package:cryptography/cryptography.dart' as cryptography; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import 'package:pointycastle/export.dart'; | 
					 | 
					 | 
					 | 
					import 'package:pointycastle/export.dart'; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					final _logger = Logger('protected_salt_generator'); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class ProtectedSaltGenerator { | 
					 | 
					 | 
					 | 
					class ProtectedSaltGenerator { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  factory ProtectedSaltGenerator(Uint8List key) { | 
					 | 
					 | 
					 | 
					  factory ProtectedSaltGenerator(Uint8List key) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    final hash = sha256.convert(key).bytes as Uint8List; | 
					 | 
					 | 
					 | 
					    final hash = sha256.convert(key).bytes as Uint8List; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -24,6 +27,10 @@ class ProtectedSaltGenerator { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  String decryptBase64(String protectedValue) { | 
					 | 
					 | 
					 | 
					  String decryptBase64(String protectedValue) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    final bytes = base64.decode(protectedValue); | 
					 | 
					 | 
					 | 
					    final bytes = base64.decode(protectedValue); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    if (bytes.isEmpty) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      _logger.warning('decoded base64 data has length 0'); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      return null; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    final result = _cipher.process(bytes); | 
					 | 
					 | 
					 | 
					    final result = _cipher.process(bytes); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    final decrypted = utf8.decode(result); | 
					 | 
					 | 
					 | 
					    final decrypted = utf8.decode(result); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return decrypted; | 
					 | 
					 | 
					 | 
					    return decrypted; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -36,34 +43,54 @@ class ProtectedSaltGenerator { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class ChachaProtectedSaltGenerator implements ProtectedSaltGenerator { | 
					 | 
					 | 
					 | 
					class ChachaProtectedSaltGenerator implements ProtectedSaltGenerator { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  ChachaProtectedSaltGenerator._(this._secretKey, this._nonce); | 
					 | 
					 | 
					 | 
					  ChachaProtectedSaltGenerator._(this._secretKey, this._nonce, this._state); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  factory ChachaProtectedSaltGenerator.create(Uint8List key) { | 
					 | 
					 | 
					 | 
					  factory ChachaProtectedSaltGenerator.create(Uint8List key) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    final hash = sha512.convert(key); | 
					 | 
					 | 
					 | 
					    final hash = sha512.convert(key); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    final secretKey = hash.bytes.sublist(0, 32); | 
					 | 
					 | 
					 | 
					    final secretKey = hash.bytes.sublist(0, 32); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    final nonce = hash.bytes.sublist(32, 32 + 12); | 
					 | 
					 | 
					 | 
					    final nonce = hash.bytes.sublist(32, 32 + 12); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return ChachaProtectedSaltGenerator._( | 
					 | 
					 | 
					 | 
					    return ChachaProtectedSaltGenerator._( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        cryptography.SecretKey(secretKey), cryptography.SecretKey(nonce)); | 
					 | 
					 | 
					 | 
					        cryptography.SecretKey(secretKey), | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        cryptography.SecretKey(nonce), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        cryptography.chacha20.newState(cryptography.SecretKey(secretKey), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            nonce: cryptography.SecretKey(nonce))); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  final cryptography.SecretKey _secretKey; | 
					 | 
					 | 
					 | 
					  final cryptography.SecretKey _secretKey; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  final cryptography.SecretKey _nonce; | 
					 | 
					 | 
					 | 
					  final cryptography.SecretKey _nonce; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  final cryptography.KeyStreamCipherState _state; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  @override | 
					 | 
					 | 
					 | 
					  @override | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  StreamCipher get _cipher => throw UnimplementedError(); | 
					 | 
					 | 
					 | 
					  StreamCipher get _cipher => throw UnimplementedError(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  @override | 
					 | 
					 | 
					 | 
					  @override | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  String decryptBase64(String protectedValue) { | 
					 | 
					 | 
					 | 
					  String decryptBase64(String protectedValue) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    final result = cryptography.chacha20 | 
					 | 
					 | 
					 | 
					    final bytes = base64.decode(protectedValue); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        .decrypt(base64.decode(protectedValue), _secretKey, nonce: _nonce); | 
					 | 
					 | 
					 | 
					    if (bytes.isEmpty) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return utf8.decode(result); | 
					 | 
					 | 
					 | 
					      _logger.warning('decoded base64 data has length 0'); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      return null; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    final result = _state.convert(bytes); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					//    try { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    _logger.fine('decoding protected value.'); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    final ret = utf8.decode(result); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    _logger.fine('Successfully decoded stuff.'); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return ret; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					//    } on FormatException catch (e, stackTrace) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					//      final ret = utf8.decode(result, allowMalformed: true); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					//      _logger.severe( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					//          'Error while decoding utf8. ignoring malformed. result: {$ret}', | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					//          e, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					//          stackTrace); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					//      return ret; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					//    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  @override | 
					 | 
					 | 
					 | 
					  @override | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  String encryptToBase64(String plainValue) { | 
					 | 
					 | 
					 | 
					  String encryptToBase64(String plainValue) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    final input = utf8.encode(plainValue) as Uint8List; | 
					 | 
					 | 
					 | 
					    final input = utf8.encode(plainValue) as Uint8List; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    final encrypted = | 
					 | 
					 | 
					 | 
					    final encrypted = _state.convert(input); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        cryptography.chacha20.encrypt(input, _secretKey, nonce: _nonce); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return base64.encode(encrypted); | 
					 | 
					 | 
					 | 
					    return base64.encode(encrypted); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  } | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					 | 
					
  |