<s> import os <EOL> import sys <EOL> import hashlib <EOL> import string <EOL> import struct <EOL> import logging <EOL> import encrypt_salsa20 <EOL> def random_string ( length ) : <EOL> try : <EOL> import M2Crypto . Rand <EOL> return M2Crypto . Rand . rand_bytes ( length ) <EOL> except ImportError : <EOL> return os . urandom ( length ) <EOL> cached_tables = { } <EOL> cached_keys = { } <EOL> def get_table ( key ) : <EOL> m = hashlib . md5 ( ) <EOL> m . update ( key ) <EOL> s = m . digest ( ) <EOL> ( a , b ) = struct . unpack ( '<STR_LIT>' , s ) <EOL> table = [ c for c in string . maketrans ( '<STR_LIT>' , '<STR_LIT>' ) ] <EOL> for i in xrange ( <NUM_LIT:1> , <NUM_LIT> ) : <EOL> table . sort ( lambda x , y : int ( a % ( ord ( x ) + i ) - a % ( ord ( y ) + i ) ) ) <EOL> return table <EOL> def init_table ( key , method = None ) : <EOL> if method is not None and method == '<STR_LIT>' : <EOL> method = None <EOL> if method : <EOL> try : <EOL> __import__ ( '<STR_LIT>' ) <EOL> except ImportError : <EOL> logging . error ( ( '<STR_LIT>' <EOL> '<STR_LIT>' ) % method ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> if not method : <EOL> if key in cached_tables : <EOL> return cached_tables [ key ] <EOL> encrypt_table = '<STR_LIT>' . join ( get_table ( key ) ) <EOL> decrypt_table = string . maketrans ( encrypt_table , <EOL> string . maketrans ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> cached_tables [ key ] = [ encrypt_table , decrypt_table ] <EOL> else : <EOL> try : <EOL> Encryptor ( key , method ) <EOL> except Exception as e : <EOL> logging . error ( e ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> def EVP_BytesToKey ( password , key_len , iv_len ) : <EOL> password = str ( password ) <EOL> r = cached_keys . get ( password , None ) <EOL> if r : <EOL> return r <EOL> m = [ ] <EOL> i = <NUM_LIT:0> <EOL> while len ( '<STR_LIT>' . join ( m ) ) < ( key_len + iv_len ) : <EOL> md5 = hashlib . md5 ( ) <EOL> data = password <EOL> if i > <NUM_LIT:0> : <EOL> data = m [ i - <NUM_LIT:1> ] + password <EOL> md5 . update ( data ) <EOL> m . append ( md5 . digest ( ) ) <EOL> i += <NUM_LIT:1> <EOL> ms = '<STR_LIT>' . join ( m ) <EOL> key = ms [ : key_len ] <EOL> iv = ms [ key_len : key_len + iv_len ] <EOL> cached_keys [ password ] = ( key , iv ) <EOL> return ( key , iv ) <EOL> method_supported = { <EOL> '<STR_LIT>' : ( <NUM_LIT:16> , <NUM_LIT:16> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT> , <NUM_LIT:16> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:32> , <NUM_LIT:16> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:16> , <NUM_LIT:8> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:16> , <NUM_LIT:16> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT> , <NUM_LIT:16> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:32> , <NUM_LIT:16> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:16> , <NUM_LIT:8> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:8> , <NUM_LIT:8> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:16> , <NUM_LIT:8> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:16> , <NUM_LIT:8> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:16> , <NUM_LIT:0> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:16> , <NUM_LIT:16> ) , <EOL> '<STR_LIT>' : ( <NUM_LIT:32> , <NUM_LIT:8> ) , <EOL> } <EOL> class Encryptor ( object ) : <EOL> def __init__ ( self , key , method = None ) : <EOL> if method == '<STR_LIT>' : <EOL> method = None <EOL> self . key = key <EOL> self . method = method <EOL> self . iv = None <EOL> self . iv_sent = False <EOL> self . cipher_iv = '<STR_LIT>' <EOL> self . decipher = None <EOL> if method : <EOL> self . cipher = self . get_cipher ( key , method , <NUM_LIT:1> , iv = random_string ( <NUM_LIT:32> ) ) <EOL> else : <EOL> self . encrypt_table , self . decrypt_table = init_table ( key ) <EOL> self . cipher = None <EOL> def get_cipher_len ( self , method ) : <EOL> method = method . lower ( ) <EOL> m = method_supported . get ( method , None ) <EOL> return m <EOL> def iv_len ( self ) : <EOL> return len ( self . cipher_iv ) <EOL> def get_cipher ( self , password , method , op , iv = None ) : <EOL> password = password . encode ( '<STR_LIT:utf-8>' ) <EOL> method = method . lower ( ) <EOL> m = self . get_cipher_len ( method ) <EOL> if m : <EOL> key , iv_ = EVP_BytesToKey ( password , m [ <NUM_LIT:0> ] , m [ <NUM_LIT:1> ] ) <EOL> if iv is None : <EOL> iv = iv_ <EOL> iv = iv [ : m [ <NUM_LIT:1> ] ] <EOL> if op == <NUM_LIT:1> : <EOL> self . cipher_iv = iv [ : m [ <NUM_LIT:1> ] ] <EOL> if method != '<STR_LIT>' : <EOL> import M2Crypto . EVP <EOL> return M2Crypto . EVP . Cipher ( method . replace ( '<STR_LIT:->' , '<STR_LIT:_>' ) , key , iv , <EOL> op , key_as_bytes = <NUM_LIT:0> , d = '<STR_LIT>' , <EOL> salt = None , i = <NUM_LIT:1> , padding = <NUM_LIT:1> ) <EOL> else : <EOL> return encrypt_salsa20 . Salsa20Cipher ( method , key , iv , op ) <EOL> logging . error ( '<STR_LIT>' % method ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> def encrypt ( self , buf ) : <EOL> if len ( buf ) == <NUM_LIT:0> : <EOL> return buf <EOL> if not self . method : <EOL> return string . translate ( buf , self . encrypt_table ) <EOL> else : <EOL> if self . iv_sent : <EOL> return self . cipher . update ( buf ) <EOL> else : <EOL> self . iv_sent = True <EOL> return self . cipher_iv + self . cipher . update ( buf ) <EOL> def decrypt ( self , buf ) : <EOL> if len ( buf ) == <NUM_LIT:0> : <EOL> return buf <EOL> if not self . method : <EOL> return string . translate ( buf , self . decrypt_table ) <EOL> else : <EOL> if self . decipher is None : <EOL> decipher_iv_len = self . get_cipher_len ( self . method ) [ <NUM_LIT:1> ] <EOL> decipher_iv = buf [ : decipher_iv_len ] <EOL> self . decipher = self . get_cipher ( self . key , self . method , <NUM_LIT:0> , <EOL> iv = decipher_iv ) <EOL> buf = buf [ decipher_iv_len : ] <EOL> if len ( buf ) == <NUM_LIT:0> : <EOL> return buf <EOL> return self . decipher . update ( buf ) <EOL> def encrypt_all ( password , method , op , data ) : <EOL> if method is not None and method . lower ( ) == '<STR_LIT>' : <EOL> method = None <EOL> if not method : <EOL> [ encrypt_table , decrypt_table ] = init_table ( password ) <EOL> if op : <EOL> return string . translate ( data , encrypt_table ) <EOL> else : <EOL> return string . translate ( data , decrypt_table ) <EOL> else : <EOL> import M2Crypto . EVP <EOL> result = [ ] <EOL> method = method . lower ( ) <EOL> ( key_len , iv_len ) = method_supported [ method ] <EOL> ( key , _ ) = EVP_BytesToKey ( password , key_len , iv_len ) <EOL> if op : <EOL> iv = random_string ( iv_len ) <EOL> result . append ( iv ) <EOL> else : <EOL> iv = data [ : iv_len ] <EOL> data = data [ iv_len : ] <EOL> if method != '<STR_LIT>' : <EOL> cipher = M2Crypto . EVP . Cipher ( method . replace ( '<STR_LIT:->' , '<STR_LIT:_>' ) , key , iv , <EOL> op , key_as_bytes = <NUM_LIT:0> , d = '<STR_LIT>' , <EOL> salt = None , i = <NUM_LIT:1> , padding = <NUM_LIT:1> ) <EOL> else : <EOL> cipher = encrypt_salsa20 . Salsa20Cipher ( method , key , iv , op ) <EOL> result . append ( cipher . update ( data ) ) <EOL> return '<STR_LIT>' . join ( result ) </s>
