class CryptoPan: def __init__(self, key): if len(key) != 32: raise CryptoPanError("Key must be a 32 byte long string") self.aes = AES(key[0:16]) self.pad = self.aes.encrypt(key[16:32]) f4bp = self.toint([ord(x) for x in self.pad[0:4]]) self.masks = [(mask, f4bp & (~mask)) for mask in (0xFFFFFFFF >> (32 - p) << (32 - p) for p in range(0, 32))] def toint(self, array): return array[0] << 24 | array[1] << 16 | array[2] << 8 | array[3] def toarray(self, n): for i in range(3, -1, -1): yield (n >> (i * 8)) & 0xFF def anonymize(self, ip): result = 0 address = [int(x) for x in ip.split(".")] if len(address) != 4: raise CryptoPanError("Invalid IPv4 Address") address = self.toint(address) def calc(a): """ calculate the first bit for Crypto-PAN""" inp = "".join((chr(x) for x in self.toarray(a))) + self.pad[4:] rin_output = self.aes.encrypt(inp) return ord(rin_output[0]) >> 7 addresses = ((address & mask[0]) | mask[1] for mask in self.masks) result = reduce(lambda x, y: x << 1 | y, (calc(a) for a in addresses), 0) return ".".join(["%s" % x for x in self.toarray(result ^ address)])
def aes_key_wrap(key, p): """ AES key wrap @type key: bytes @param key: Key; length MUST be 16, 24, or 32 octets @type p : bytes @param p : Plaintext; length MUST be a multiple of 8 octets @rtype: bytes @return: Wrapped version of plaintext """ assert (len(p) % 8 == 0) n = len(p) / 8 r = list(range(n + 1)) r[0] = b'\0\0\0\0\0\0\0\0' for i in range(1, n + 1): r[i] = p[(i - 1) * 8:i * 8] a = b'\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6' aes = AESCipher(key) for j in range(0, 6): for i in range(1, n + 1): t = pack("!q", (n * j) + i) b = aes.encrypt(a + r[i]) # B = AES(K, A | R[i]) a = strxor(b[:8], t) # A = MSB(64, B) ^ t where t = (n*j)+i r[i] = b[8:] # R[i] = LSB(64, B) r[0] = a return "".join(r)
def encrypt(self): key = "@[email protected]" iv = chr(0) * 16 aes = AESCipher(key, mode=MODE_ECB, IV=iv) fulltext = self.gcode.text padded = Padding.appendPadding(fulltext) enc_text = aes.encrypt(padded) magic = "3DPFNKG13WTW" magic2 = struct.pack("8B", 1, 2, 0, 0, 0, 0, 18, 76) blanks = chr(0) * 4684 tag = "TagEJ256" magic3 = struct.pack("4B", 0, 0, 0, 68) crc32 = binascii.crc32(enc_text) crcstr = struct.pack(">l", crc32) encrypted_header = self.encrypt_header() bio = BytesIO() bio.write(magic) bio.write(magic2) bio.write(blanks) bio.write(tag) bio.write(magic3) bio.write(crcstr) bio.write((chr(0) * (68 - len(crcstr)))) log.debug("Length of encrypted header: {}".format( len(encrypted_header))) if len(encrypted_header) > (8192 - bio.tell()): log.error("Header is too big to fit file format!") bio.write(encrypted_header) left = 8192 - bio.tell() bio.write((chr(0) * left)) bio.write(enc_text) return bio.getvalue()
def encrypt_header(self): key = "@xyzprinting.com" iv = chr(0) * 16 aes = AESCipher(key, mode=MODE_CBC, IV=iv) text = self.gcode.header_text header = Padding.appendPadding(text) return aes.encrypt(header)
def apply_aes_ctr(key, nonce, source): cipher = AESCipher(key) dest = b"" for (i, cipher_block) in generate_blocks(source, BLOCK_SIZE): pre_enc = add_bytestrings(nonce, int_to_bytes(i, BLOCK_SIZE)) enc = cipher.encrypt(pre_enc) dest_block = xor_bytestrings(enc, cipher_block) dest += dest_block return dest
def aes_encrypt(msg, key=None): msg = _aes_pad(msg) global _aes if key is not None: _aes_local = AESCipher(key) ret = _aes_local.encrypt(msg) else: ret = _aes.encrypt(msg) ret = base64.b64encode(ret) return ret
class CryptoPan(): def __init__(self, key): if len(key) != 32: raise CryptoPanError("Key must be a 32 byte long string") self.aes = AES(key[0:16]) self.pad = self.aes.encrypt(key[16:32]) self.first4bytes_pad = self.toint([ord(x) for x in self.pad[0:4]]) def toint(self, array): return array[0] << 24 | array[1] << 16 | array[2] << 8 | array[3] def toarray(self, n): for i in range(3, -1, -1): yield (n >> (i * 8)) & 0xFF def anonymize(self, ip): result = 0 address = [int(x) for x in ip.split(".")] if len(address) != 4: raise CryptoPanError("Invalid IPv4 Address") address = self.toint(address) def calc(a): """ calculate the first bit for Crypto-PAN""" inp = "".join([chr(x) for x in self.toarray(a)]) + self.pad[4:] rin_output = self.aes.encrypt(inp) return ord(rin_output[0]) >> 7 def prep_addr(p, address): """ prepare adress for calculation """ mask = 0xFFFFFFFF >> (32 - p) << (32 - p) return (address & mask) | (self.first4bytes_pad & (~mask)) addresses = [prep_addr(p, address) for p in range(0, 32)] result = reduce(lambda x, y: x << 1 | y, [calc(a) for a in addresses], 0) return ".".join(["%s" % x for x in self.toarray(result ^ address)])
def encrypt_aes_cbc(key, plaintext): padded_plaintext = pad_pkcs7(plaintext) cipher = AESCipher(key) iv = cryptorandom(BLOCK_SIZE) pre_xor = iv ciphertext = b"" for (i, plaintext_block) in generate_blocks(padded_plaintext, BLOCK_SIZE): xord = xor_bytestrings(plaintext_block, pre_xor) cipher_block = cipher.encrypt(xord) ciphertext += cipher_block pre_xor = cipher_block return iv + ciphertext
def format_secret(session, secret, content_type): """Formats `secret` to make possible to pass it to the Secret Service API.""" if not isinstance(secret, bytes): secret = secret.encode('utf-8') if not session.encrypted: return dbus.Struct( (session.object_path, '', dbus.ByteArray(secret), content_type)) # PKCS-7 style padding padding = 0x10 - (len(secret) & 0xf) secret += bytes(bytearray((padding, )) * padding) aes_iv = long_to_bytes(getrandbits(0x80)) # If shorter than 16 bytes, prepend zero bytes aes_iv = b'\x00' * (0x10 - len(aes_iv)) + aes_iv aes_cipher = AESCipher(session.aes_key, mode=MODE_CBC, IV=aes_iv) return dbus.Struct( (session.object_path, dbus.Array(aes_iv), dbus.Array(bytearray(aes_cipher.encrypt(secret))), content_type))
def format_secret(session, secret, content_type): """Formats `secret` to make possible to pass it to the Secret Service API.""" if not isinstance(secret, bytes): secret = secret.encode('utf-8') if not session.encrypted: return dbus.Struct((session.object_path, '', dbus.ByteArray(secret), content_type)) # PKCS-7 style padding padding = 0x10 - (len(secret) & 0xf) secret += bytes(bytearray((padding,)) * padding) aes_iv = get_random_bytes(block_size) aes_cipher = AESCipher(session.aes_key, mode=MODE_CBC, IV=aes_iv) return dbus.Struct(( session.object_path, dbus.Array(aes_iv), dbus.Array(bytearray(aes_cipher.encrypt(secret))), content_type ))
def aes_key_wrap(key, p): assert( len(p) % 8 == 0 ) n = len(p)/8 r = range(n+1) r[0] = b'\0\0\0\0\0\0\0\0' for i in range(1,n+1): r[i] = p[(i-1)*8:i*8] a = b'\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6' aes = AESCipher(key) for j in range(0,6): for i in range(1,n+1): t = struct.pack("!q", (n*j)+i) b = aes.encrypt(a+r[i]) # B = AES(K, A | R[i]) a = strxor(b[:8], t) # A = MSB(64, B) ^ t where t = (n*j)+i r[i] = b[8:] # R[i] = LSB(64, B) r[0] = a return "".join(r)
def aes_key_wrap(key, p): assert (len(p) % 8 == 0) n = len(p) / 8 r = range(n + 1) r[0] = b'\0\0\0\0\0\0\0\0' for i in range(1, n + 1): r[i] = p[(i - 1) * 8:i * 8] a = b'\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6' aes = AESCipher(key) for j in range(0, 6): for i in range(1, n + 1): t = struct.pack("!q", (n * j) + i) b = aes.encrypt(a + r[i]) # B = AES(K, A | R[i]) a = strxor(b[:8], t) # A = MSB(64, B) ^ t where t = (n*j)+i r[i] = b[8:] # R[i] = LSB(64, B) r[0] = a return "".join(r)
def encrypt(message: bytes, aes: AES.AESCipher) -> bytes: """Chiffre une chaine d'octets Chiffrement d'une chaine codée sur un multiple de 16 octets. Le chiffrement est effectué à l'aide de l'AES, fourni au préalable. La fonction retourne donc la chaine chiffrée. Un Zero Padding est appliqué. """ # Convert eventual not-bytes object to bytes message = pickle.dumps(message) # Convert sequence of bytes to acii-compatible sequence of bytes message = binascii.hexlify(message) # Crypto.Cipher.AES.AESCipher needs an ASCII string to work on message_str = message.decode('ascii') # Section with zero-padding logic length = len(message_str) # Adding a position for the header value length += 1 # Calculating length of needed padding if (length % 16) != 0: complement_size = 16 - (length % 16) else: complement_size = 0 # Header holds the size of added padding header = hex(complement_size) # Stripping leading "0x" by keeping only last char header = header[-1] # Creating padding ASCII string with zeros complement = "0" * complement_size # Merging header message and padding message_str = "".join([header, message_str, complement]) # Encrypt zero-padded message return aes.encrypt(message_str)
def format_secret(session, secret, content_type): """Formats `secret` to make possible to pass it to the Secret Service API.""" if not isinstance(secret, bytes): secret = secret.encode('utf-8') if not session.encrypted: return dbus.Struct((session.object_path, '', dbus.ByteArray(secret), content_type)) # PKCS-7 style padding padding = 0x10 - (len(secret) & 0xf) secret += bytes(bytearray((padding,)) * padding) aes_iv = long_to_bytes(getrandbits(0x80)) # If shorter than 16 bytes, prepend zero bytes aes_iv = b'\x00' * (0x10 - len(aes_iv)) + aes_iv aes_cipher = AESCipher(session.aes_key, mode=MODE_CBC, IV=aes_iv) return dbus.Struct(( session.object_path, dbus.Array(aes_iv), dbus.Array(bytearray(aes_cipher.encrypt(secret))), content_type ))
def decrypt_AES128CCM(key, n, M, c, a): # Set parameters L = 15-len(n) ln = len(n) la = len(a) lm = len(c) - M lblock = AES.block_size assert( L >= 2 and L <= 8 ) assert( lm < (1<<(8*L)) ) aes = AESCipher(key) # PART 1: Compute the key stream to get MAC value and authentication tag U = c[-M:] Lp = L-1 Flags = struct.pack("B", Lp) i = 0 A0 = Flags + n + struct.pack("!Q", 0)[-L:] S0 = aes.encrypt(A0) T = strxor(U, S0[:M]) remaining = lm S = b'' while remaining >= lblock: remaining -= lblock i += 1 Ai = Flags + n + struct.pack("!Q", i)[-L:] Si = aes.encrypt(Ai) S = S + Si i += 1 Aend = Flags + n + struct.pack("!Q", i)[-L:] Send = aes.encrypt(Aend)[:remaining] S = S + Send m = strxor(c[:-M], S) # PART 2: Compute the MAC to verify the authentication tag # Note: With no data, this is just AES-CBC with B0 as the IV Adata = 0 if la > 0: Adata = 1 Mp = (M-2)/2 Lp = L-1 Flags = 64*Adata + 8*Mp + Lp B = struct.pack("B", Flags) + n + struct.pack("!Q", lm)[-L:] # If there is associated data, append it if la > 0: # Encode the length La = b'' if (la < 2**16 - 2**8): La = struct.pack("!H", la) elif (la < 2**32): La = b'\xFF\xFE' + struct.pack("!I", la) elif (la < 2**64): La = b'\xFF\xFE' + struct.pack("!Q", la) lla = len(La) # Compute the amount of zero-padding we need lza = lblock - ((la + lla)%lblock) B = B + La + a + b'\0'*lza # Append the message lzm = lblock - (lm % lblock) B = B + m + b'\0'*lzm nB = len(B) / lblock # Compute the CBC-MAC X = aes.encrypt( B[:lblock] ) for i in range(nB-1): X = strxor( X, B[ lblock*(i+1) : lblock*(i+2) ] ) X = aes.encrypt(X) if T != X[:M]: raise Exception("Integrity check failed") return m
def encrypt_AES128CCM(key, n, M, m, a): # Set parameters ln = len(n) lm = len(m) la = len(a) lblock = AES.block_size L = 15-len(n) assert( L >= 2 and L <= 8 ) assert( lm < (1<<(8*L)) ) aes = AESCipher(key) # PART 1: Compute the authentication tag # Note: With no data, this is just AES-CBC with B0 as the IV Adata = 0 if la > 0: Adata = 1 Mp = (M-2)/2 Lp = L-1 Flags = 64*Adata + 8*Mp + Lp B = struct.pack("B", Flags) + n + struct.pack("!Q", lm)[-L:] # If there is associated data, append it if la > 0: # Encode the length La = b'' if (la < 2**16 - 2**8): La = struct.pack("!H", la) elif (la < 2**32): La = b'\xFF\xFE' + struct.pack("!I", la) elif (la < 2**64): La = b'\xFF\xFE' + struct.pack("!Q", la) lla = len(La) # Compute the amount of zero-padding we need lza = lblock - ((la + lla)%lblock) B = B + La + a + b'\0'*lza # Append the message lzm = lblock - (lm % lblock) B = B + m + b'\0'*lzm nB = len(B) / lblock # Compute the CBC-MAC X = aes.encrypt( B[:lblock] ) for i in range(nB-1): X = strxor( X, B[ lblock*(i+1) : lblock*(i+2) ] ) X = aes.encrypt(X) T = X[:M] # PART 2: Encrypt the message Flags = struct.pack("B", Lp) i=0 A0 = Flags + n + struct.pack("!Q", i)[-L:] S0 = aes.encrypt(A0) U = strxor(T, S0[:M]) remaining = lm S = b'' while remaining >= lblock: remaining -= lblock i += 1 Ai = Flags + n + struct.pack("!Q", i)[-L:] Si = aes.encrypt(Ai) S = S + Si i += 1 Aend = Flags + n + struct.pack("!Q", i)[-L:] Send = aes.encrypt(Aend)[:remaining] S = S + Send c = strxor(m, S) return c+U
def decrypt_AES128CCM(key, n, M, c, a): # Set parameters L = 15 - len(n) ln = len(n) la = len(a) lm = len(c) - M lblock = AES.block_size assert (L >= 2 and L <= 8) assert (lm < (1 << (8 * L))) aes = AESCipher(key) # PART 1: Compute the key stream to get MAC value and authentication tag U = c[-M:] Lp = L - 1 Flags = struct.pack("B", Lp) i = 0 A0 = Flags + n + struct.pack("!Q", 0)[-L:] S0 = aes.encrypt(A0) T = strxor(U, S0[:M]) remaining = lm S = b'' while remaining >= lblock: remaining -= lblock i += 1 Ai = Flags + n + struct.pack("!Q", i)[-L:] Si = aes.encrypt(Ai) S = S + Si i += 1 Aend = Flags + n + struct.pack("!Q", i)[-L:] Send = aes.encrypt(Aend)[:remaining] S = S + Send m = strxor(c[:-M], S) # PART 2: Compute the MAC to verify the authentication tag # Note: With no data, this is just AES-CBC with B0 as the IV Adata = 0 if la > 0: Adata = 1 Mp = (M - 2) / 2 Lp = L - 1 Flags = 64 * Adata + 8 * Mp + Lp B = struct.pack("B", Flags) + n + struct.pack("!Q", lm)[-L:] # If there is associated data, append it if la > 0: # Encode the length La = b'' if (la < 2**16 - 2**8): La = struct.pack("!H", la) elif (la < 2**32): La = b'\xFF\xFE' + struct.pack("!I", la) elif (la < 2**64): La = b'\xFF\xFE' + struct.pack("!Q", la) lla = len(La) # Compute the amount of zero-padding we need lza = lblock - ((la + lla) % lblock) B = B + La + a + b'\0' * lza # Append the message lzm = lblock - (lm % lblock) B = B + m + b'\0' * lzm nB = len(B) / lblock # Compute the CBC-MAC X = aes.encrypt(B[:lblock]) for i in range(nB - 1): X = strxor(X, B[lblock * (i + 1):lblock * (i + 2)]) X = aes.encrypt(X) if T != X[:M]: raise Exception("Integrity check failed") return m
def encrypt_AES128CCM(key, n, M, m, a): # Set parameters ln = len(n) lm = len(m) la = len(a) lblock = AES.block_size L = 15 - len(n) assert (L >= 2 and L <= 8) assert (lm < (1 << (8 * L))) assert (2 <= M and M <= 16 and M % 2 == 0) aes = AESCipher(key) # PART 1: Compute the authentication tag # Note: With no data, this is just AES-CBC with B0 as the IV Adata = 0 if la > 0: Adata = 1 Mp = (M - 2) / 2 Lp = L - 1 Flags = 64 * Adata + 8 * Mp + Lp B = struct.pack("B", Flags) + n + struct.pack("!Q", lm)[-L:] # If there is associated data, append it if la > 0: # Encode the length La = b'' if (la < 2**16 - 2**8): La = struct.pack("!H", la) elif (la < 2**32): La = b'\xFF\xFE' + struct.pack("!I", la) elif (la < 2**64): La = b'\xFF\xFE' + struct.pack("!Q", la) lla = len(La) # Compute the amount of zero-padding we need lza = lblock - ((la + lla) % lblock) B = B + La + a + b'\0' * lza # Append the message lzm = lblock - (lm % lblock) B = B + m + b'\0' * lzm nB = len(B) / lblock # Compute the CBC-MAC X = aes.encrypt(B[:lblock]) for i in range(nB - 1): X = strxor(X, B[lblock * (i + 1):lblock * (i + 2)]) X = aes.encrypt(X) T = X[:M] # PART 2: Encrypt the message Flags = struct.pack("B", Lp) i = 0 A0 = Flags + n + struct.pack("!Q", i)[-L:] S0 = aes.encrypt(A0) U = strxor(T, S0[:M]) remaining = lm S = b'' while remaining >= lblock: remaining -= lblock i += 1 Ai = Flags + n + struct.pack("!Q", i)[-L:] Si = aes.encrypt(Ai) S = S + Si i += 1 Aend = Flags + n + struct.pack("!Q", i)[-L:] Send = aes.encrypt(Aend)[:remaining] S = S + Send c = strxor(m, S) return c + U
def VotaHandler(request, ident, usuario=None): response = HttpResponse("", content_type='application/json', status=200) ans = {} ans['error'] = 0 if request.method == 'GET': pg = request.GET.get('pg', None) enc = request.GET.get('enc', None) dec = request.GET.get('dec', None) if (pg is None): raise ParametrosIncompletosException() if (enc is not None): pas = darPassDePg(pg) ans['pas'] = pas motor = AESCipher(pas) ans['ans'] = motor.encrypt(enc); response.write(simplejson.dumps(ans)) return response elif (dec is not None): pas = darPassDePg(pg) ans['pas'] = pas motor = AESCipher(pas) ans['ans'] = motor.decrypt(dec); response.write(simplejson.dumps(ans)) return response usr = request.GET.get('u', None) vot = request.GET.get('v', None) if (usr is None or vot is None): raise ParametrosIncompletosException() consulta = [ 'per.'+usr+'.humId', 'per.'+usr+'.nom', 'global.votacion', ] datos = buscarTuplas(pg, consulta) datos = to_dict_simple(datos, None, True, ['id', 'i', 'd', 'sd']) if ((not ('global.votacion' in datos)) or datos['global.votacion'] is None): raise MalaPeticionException() rutaVotacion = datos['global.votacion'] consulta = [ rutaVotacion+'.pregunta', rutaVotacion+'.opciones.'+vot+'.txt', ] datos2 = buscarTuplas(pg, consulta) datos2 = to_dict_simple(datos2, None, True, ['id', 'i', 'd', 'sd']) payloadModificacion = {"dat":{ rutaVotacion+'.resultado.u.'+usr: simplejson.dumps(vot) },"acc":"+"} crearTuplas(pg, payloadModificacion) llave = ndb.Key('Pagina', comun.leerNumero(pg)) unapagina = llave.get() publicar(unapagina.usr, unapagina.path, pg, payloadModificacion) ans['msg'] = datos2[rutaVotacion+'.pregunta']+' '+datos['per.'+usr+'.humId']+' vota por "'+datos2[rutaVotacion+'.opciones.'+vot+'.txt']+'"' #ans['msg1'] = datos #ans['msg2'] = datos2 #ans['creacion'] = creacion response.write(simplejson.dumps(ans)) return response