]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/aes.py
   1 __all__ 
= ['aes_encrypt', 'key_expansion', 'aes_ctr_decrypt', 'aes_cbc_decrypt', 'aes_decrypt_text'] 
   6 from .utils 
import bytes_to_intlist
, intlist_to_bytes
 
  10 def aes_ctr_decrypt(data
, key
, counter
): 
  12     Decrypt with aes in counter mode 
  14     @param {int[]} data        cipher 
  15     @param {int[]} key         16/24/32-Byte cipher key 
  16     @param {instance} counter  Instance whose next_value function (@returns {int[]}  16-Byte block) 
  17                                returns the next counter block 
  18     @returns {int[]}           decrypted data 
  20     expanded_key 
= key_expansion(key
) 
  21     block_count 
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
)) 
  24     for i 
in range(block_count
): 
  25         counter_block 
= counter
.next_value() 
  26         block 
= data
[i
*BLOCK_SIZE_BYTES 
: (i
+1)*BLOCK_SIZE_BYTES
] 
  27         block 
+= [0]*(BLOCK_SIZE_BYTES 
- len(block
)) 
  29         cipher_counter_block 
= aes_encrypt(counter_block
, expanded_key
) 
  30         decrypted_data 
+= xor(block
, cipher_counter_block
) 
  31     decrypted_data 
= decrypted_data
[:len(data
)] 
  35 def aes_cbc_decrypt(data
, key
, iv
): 
  37     Decrypt with aes in CBC mode 
  39     @param {int[]} data        cipher 
  40     @param {int[]} key         16/24/32-Byte cipher key 
  41     @param {int[]} iv          16-Byte IV 
  42     @returns {int[]}           decrypted data 
  44     expanded_key 
= key_expansion(key
) 
  45     block_count 
= int(ceil(float(len(data
)) / BLOCK_SIZE_BYTES
)) 
  48     previous_cipher_block 
= iv
 
  49     for i 
in range(block_count
): 
  50         block 
= data
[i
*BLOCK_SIZE_BYTES 
: (i
+1)*BLOCK_SIZE_BYTES
] 
  51         block 
+= [0]*(BLOCK_SIZE_BYTES 
- len(block
)) 
  53         decrypted_block 
= aes_decrypt(block
, expanded_key
) 
  54         decrypted_data 
+= xor(decrypted_block
, previous_cipher_block
) 
  55         previous_cipher_block 
= block
 
  56     decrypted_data 
= decrypted_data
[:len(data
)] 
  60 def key_expansion(data
): 
  64     @param {int[]} data  16/24/32-Byte cipher key 
  65     @returns {int[]}     176/208/240-Byte expanded key  
  69     key_size_bytes 
= len(data
) 
  70     expanded_key_size_bytes 
= (key_size_bytes 
// 4 + 7) * BLOCK_SIZE_BYTES
 
  72     while len(data
) < expanded_key_size_bytes
: 
  74         temp 
= key_schedule_core(temp
, rcon_iteration
) 
  76         data 
+= xor(temp
, data
[-key_size_bytes 
: 4-key_size_bytes
]) 
  80             data 
+= xor(temp
, data
[-key_size_bytes 
: 4-key_size_bytes
]) 
  82         if key_size_bytes 
== 32: 
  84             temp 
= sub_bytes(temp
) 
  85             data 
+= xor(temp
, data
[-key_size_bytes 
: 4-key_size_bytes
]) 
  87         for _ 
in range(3 if key_size_bytes 
== 32  else 2 if key_size_bytes 
== 24 else 0): 
  89             data 
+= xor(temp
, data
[-key_size_bytes 
: 4-key_size_bytes
]) 
  90     data 
= data
[:expanded_key_size_bytes
] 
  94 def aes_encrypt(data
, expanded_key
): 
  96     Encrypt one block with aes 
  98     @param {int[]} data          16-Byte state 
  99     @param {int[]} expanded_key  176/208/240-Byte expanded key  
 100     @returns {int[]}             16-Byte cipher 
 102     rounds 
= len(expanded_key
) // BLOCK_SIZE_BYTES 
- 1 
 104     data 
= xor(data
, expanded_key
[:BLOCK_SIZE_BYTES
]) 
 105     for i 
in range(1, rounds
+1): 
 106         data 
= sub_bytes(data
) 
 107         data 
= shift_rows(data
) 
 109             data 
= mix_columns(data
) 
 110         data 
= xor(data
, expanded_key
[i
*BLOCK_SIZE_BYTES 
: (i
+1)*BLOCK_SIZE_BYTES
]) 
 114 def aes_decrypt(data
, expanded_key
): 
 116     Decrypt one block with aes 
 118     @param {int[]} data          16-Byte cipher 
 119     @param {int[]} expanded_key  176/208/240-Byte expanded key 
 120     @returns {int[]}             16-Byte state 
 122     rounds 
= len(expanded_key
) // BLOCK_SIZE_BYTES 
- 1 
 124     for i 
in range(rounds
, 0, -1): 
 125         data 
= xor(data
, expanded_key
[i
*BLOCK_SIZE_BYTES 
: (i
+1)*BLOCK_SIZE_BYTES
]) 
 127             data 
= mix_columns_inv(data
) 
 128         data 
= shift_rows_inv(data
) 
 129         data 
= sub_bytes_inv(data
) 
 130     data 
= xor(data
, expanded_key
[:BLOCK_SIZE_BYTES
]) 
 134 def aes_decrypt_text(data
, password
, key_size_bytes
): 
 137     - The first 8 Bytes of decoded 'data' are the 8 high Bytes of the counter 
 138     - The cipher key is retrieved by encrypting the first 16 Byte of 'password' 
 139       with the first 'key_size_bytes' Bytes from 'password' (if necessary filled with 0's) 
 140     - Mode of operation is 'counter' 
 142     @param {str} data                    Base64 encoded string 
 143     @param {str,unicode} password        Password (will be encoded with utf-8) 
 144     @param {int} key_size_bytes          Possible values: 16 for 128-Bit, 24 for 192-Bit or 32 for 256-Bit 
 145     @returns {str}                       Decrypted data 
 147     NONCE_LENGTH_BYTES 
= 8 
 149     data 
= bytes_to_intlist(base64
.b64decode(data
)) 
 150     password 
= bytes_to_intlist(password
.encode('utf-8')) 
 152     key 
= password
[:key_size_bytes
] + [0]*(key_size_bytes 
- len(password
)) 
 153     key 
= aes_encrypt(key
[:BLOCK_SIZE_BYTES
], key_expansion(key
)) * (key_size_bytes 
// BLOCK_SIZE_BYTES
) 
 155     nonce 
= data
[:NONCE_LENGTH_BYTES
] 
 156     cipher 
= data
[NONCE_LENGTH_BYTES
:] 
 159         __value 
= nonce 
+ [0]*(BLOCK_SIZE_BYTES 
- NONCE_LENGTH_BYTES
) 
 160         def next_value(self
): 
 162             self
.__value 
= inc(self
.__value
) 
 165     decrypted_data 
= aes_ctr_decrypt(cipher
, key
, Counter()) 
 166     plaintext 
= intlist_to_bytes(decrypted_data
) 
 170 RCON 
= (0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36) 
 171 SBOX 
= (0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 
 172         0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 
 173         0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 
 174         0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 
 175         0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 
 176         0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 
 177         0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 
 178         0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 
 179         0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 
 180         0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 
 181         0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 
 182         0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 
 183         0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 
 184         0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 
 185         0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 
 186         0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16) 
 187 SBOX_INV 
= (0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 
 188             0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 
 189             0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 
 190             0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 
 191             0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 
 192             0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 
 193             0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 
 194             0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 
 195             0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 
 196             0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 
 197             0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 
 198             0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 
 199             0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 
 200             0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 
 201             0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 
 202             0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d) 
 203 MIX_COLUMN_MATRIX 
= ((0x2,0x3,0x1,0x1), 
 207 MIX_COLUMN_MATRIX_INV 
= ((0xE,0xB,0xD,0x9), 
 211 RIJNDAEL_EXP_TABLE 
= (0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35, 
 212                       0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA, 
 213                       0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31, 
 214                       0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD, 
 215                       0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88, 
 216                       0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A, 
 217                       0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3, 
 218                       0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0, 
 219                       0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41, 
 220                       0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75, 
 221                       0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80, 
 222                       0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54, 
 223                       0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA, 
 224                       0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E, 
 225                       0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17, 
 226                       0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01) 
 227 RIJNDAEL_LOG_TABLE 
= (0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1a, 0xc6, 0x4b, 0xc7, 0x1b, 0x68, 0x33, 0xee, 0xdf, 0x03, 
 228                       0x64, 0x04, 0xe0, 0x0e, 0x34, 0x8d, 0x81, 0xef, 0x4c, 0x71, 0x08, 0xc8, 0xf8, 0x69, 0x1c, 0xc1, 
 229                       0x7d, 0xc2, 0x1d, 0xb5, 0xf9, 0xb9, 0x27, 0x6a, 0x4d, 0xe4, 0xa6, 0x72, 0x9a, 0xc9, 0x09, 0x78, 
 230                       0x65, 0x2f, 0x8a, 0x05, 0x21, 0x0f, 0xe1, 0x24, 0x12, 0xf0, 0x82, 0x45, 0x35, 0x93, 0xda, 0x8e, 
 231                       0x96, 0x8f, 0xdb, 0xbd, 0x36, 0xd0, 0xce, 0x94, 0x13, 0x5c, 0xd2, 0xf1, 0x40, 0x46, 0x83, 0x38, 
 232                       0x66, 0xdd, 0xfd, 0x30, 0xbf, 0x06, 0x8b, 0x62, 0xb3, 0x25, 0xe2, 0x98, 0x22, 0x88, 0x91, 0x10, 
 233                       0x7e, 0x6e, 0x48, 0xc3, 0xa3, 0xb6, 0x1e, 0x42, 0x3a, 0x6b, 0x28, 0x54, 0xfa, 0x85, 0x3d, 0xba, 
 234                       0x2b, 0x79, 0x0a, 0x15, 0x9b, 0x9f, 0x5e, 0xca, 0x4e, 0xd4, 0xac, 0xe5, 0xf3, 0x73, 0xa7, 0x57, 
 235                       0xaf, 0x58, 0xa8, 0x50, 0xf4, 0xea, 0xd6, 0x74, 0x4f, 0xae, 0xe9, 0xd5, 0xe7, 0xe6, 0xad, 0xe8, 
 236                       0x2c, 0xd7, 0x75, 0x7a, 0xeb, 0x16, 0x0b, 0xf5, 0x59, 0xcb, 0x5f, 0xb0, 0x9c, 0xa9, 0x51, 0xa0, 
 237                       0x7f, 0x0c, 0xf6, 0x6f, 0x17, 0xc4, 0x49, 0xec, 0xd8, 0x43, 0x1f, 0x2d, 0xa4, 0x76, 0x7b, 0xb7, 
 238                       0xcc, 0xbb, 0x3e, 0x5a, 0xfb, 0x60, 0xb1, 0x86, 0x3b, 0x52, 0xa1, 0x6c, 0xaa, 0x55, 0x29, 0x9d, 
 239                       0x97, 0xb2, 0x87, 0x90, 0x61, 0xbe, 0xdc, 0xfc, 0xbc, 0x95, 0xcf, 0xcd, 0x37, 0x3f, 0x5b, 0xd1, 
 240                       0x53, 0x39, 0x84, 0x3c, 0x41, 0xa2, 0x6d, 0x47, 0x14, 0x2a, 0x9e, 0x5d, 0x56, 0xf2, 0xd3, 0xab, 
 241                       0x44, 0x11, 0x92, 0xd9, 0x23, 0x20, 0x2e, 0x89, 0xb4, 0x7c, 0xb8, 0x26, 0x77, 0x99, 0xe3, 0xa5, 
 242                       0x67, 0x4a, 0xed, 0xde, 0xc5, 0x31, 0xfe, 0x18, 0x0d, 0x63, 0x8c, 0x80, 0xc0, 0xf7, 0x70, 0x07) 
 245     return [SBOX
[x
] for x 
in data
] 
 247 def sub_bytes_inv(data
): 
 248     return [SBOX_INV
[x
] for x 
in data
] 
 251     return data
[1:] + [data
[0]] 
 253 def key_schedule_core(data
, rcon_iteration
): 
 255     data 
= sub_bytes(data
) 
 256     data
[0] = data
[0] ^ RCON
[rcon_iteration
] 
 260 def xor(data1
, data2
): 
 261     return [x^y 
for x
, y 
in zip(data1
, data2
)] 
 263 def rijndael_mul(a
, b
): 
 266     return RIJNDAEL_EXP_TABLE
[(RIJNDAEL_LOG_TABLE
[a
] + RIJNDAEL_LOG_TABLE
[b
]) % 0xFF] 
 268 def mix_column(data
, matrix
): 
 272         for column 
in range(4): 
 274             mixed ^
= rijndael_mul(data
[column
], matrix
[row
][column
]) 
 275         data_mixed
.append(mixed
) 
 278 def mix_columns(data
, matrix
=MIX_COLUMN_MATRIX
): 
 281         column 
= data
[i
*4 : (i
+1)*4] 
 282         data_mixed 
+= mix_column(column
, matrix
) 
 285 def mix_columns_inv(data
): 
 286     return mix_columns(data
, MIX_COLUMN_MATRIX_INV
) 
 288 def shift_rows(data
): 
 290     for column 
in range(4): 
 292             data_shifted
.append( data
[((column 
+ row
) & 0b11) * 4 + row
] ) 
 295 def shift_rows_inv(data
): 
 297     for column 
in range(4): 
 299             data_shifted
.append( data
[((column 
- row
) & 0b11) * 4 + row
] ) 
 303     data 
= data
[:] # copy 
 304     for i 
in range(len(data
)-1,-1,-1): 
 308             data
[i
] = data
[i
] + 1