def encode_msg(self, msg): """Apply security layer and return encode MSG in Json :param msg: xAAL msg instance :type msg: Message :return: return an xAAL msg ciphered and serialized in json :rtype: json """ result = {} # Format data msg to send result['version'] = msg.version result['targets'] = json.dumps(msg.targets) result['timestamp'] = msg.timestamp # Format payload before ciphering if msg.body: buf = json.dumps({"header": msg.header, "body": msg.body}) else: buf = json.dumps({"header": msg.header}) # Payload Ciphering: ciph # Additionnal Data == json serialization of the targets array payload = buf.encode('utf-8') ad = json.dumps(msg.targets).encode('utf-8') # Additional Data nonce = build_nonce(msg.timestamp) ciph = pysodium.crypto_aead_chacha20poly1305_ietf_encrypt( payload, ad, nonce, self.cipher_key) # Add payload: base64 encoded of payload cipher result['payload'] = base64.b64encode(ciph) # Json serialization return json.dumps(result)
def constructSTSResponse(self, mType, addr, exchangeData): data = None addrStr = sts_utility.addrToString(addr) if addrStr in STS.STSConnectionStates.keys(): if STS.STSConnectionStates[addrStr][ 'cSuite'] == 1 or STS.STSConnectionStates[addrStr][ 'cSuite'] == 4: nonce = pysodium.randombytes( pysodium.crypto_aead_chacha20poly1305_ietf_NONCEBYTES) m = struct.pack('>B', mType) + struct.pack('>I', len(nonce)) # T = struct.pack('>Q', int(time.time())) encrypData = pysodium.crypto_aead_chacha20poly1305_ietf_encrypt( exchangeData, m, nonce, STS.STSConnectionStates[addrStr]['session_key'][:32]) data = m + nonce + encrypData elif STS.STSConnectionStates[addrStr][ 'cSuite'] == 2 or STS.STSConnectionStates[addrStr][ 'cSuite'] == 5: nonce = pysodium.randombytes( pysodium.crypto_aead_chacha20poly1305_NONCEBYTES) m = struct.pack('>B', mType) + struct.pack('>I', len(nonce)) # T = struct.pack('>Q', int(time.time())) encrypData = pysodium.crypto_aead_chacha20poly1305_encrypt( exchangeData, m, nonce, STS.STSConnectionStates[addrStr]['session_key'][:32]) data = m + nonce + encrypData # print(binascii.hexlify(T)) # print(binascii.hexlify(pysodium.crypto_aead_chacha20poly1305_ietf_decrypt(encrypData, m, nonce, myTX[:32]))) return data
def test_aead_chacha20poly1305_ietf(self): if not pysodium.sodium_version_check(1, 0, 4): return key = binascii.unhexlify(b"4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007") input_ = binascii.unhexlify(b"86d09974840bded2a5ca") nonce = binascii.unhexlify(b"cd7cf67be39c794a") ad = binascii.unhexlify(b"87e229d4500845a079c0") output = pysodium.crypto_aead_chacha20poly1305_ietf_encrypt(input_, ad, nonce, key) output = pysodium.crypto_aead_chacha20poly1305_ietf_decrypt(output, ad, nonce, key) self.assertEqual(output, input_)
def test_aead_chacha20poly1305_ietf(self): if not pysodium.sodium_version_check(1, 0, 4): return key = binascii.unhexlify(b"4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007") input_ = binascii.unhexlify(b"86d09974840bded2a5ca") nonce = binascii.unhexlify(b"cd7cf67be39c794acd7cf67b") for ad in [binascii.unhexlify(b"87e229d4500845a079c0"), None]: output = pysodium.crypto_aead_chacha20poly1305_ietf_encrypt(input_, ad, nonce, key) output = pysodium.crypto_aead_chacha20poly1305_ietf_decrypt(output, ad, nonce, key) self.assertEqual(output, input_)
def test(msg, aad, nonce, key): ct = pysodium.crypto_aead_chacha20poly1305_ietf_encrypt( msg, aad, nonce, key) ct, tag = ct[:len(msg)], ct[len(msg):] print """ vector("%s", "%s", "%s", "%s", "%s", "%s");""" % (key.encode('hex'), nonce.encode('hex'), aad.encode('hex'), msg.encode('hex'), ct.encode('hex'), tag.encode('hex'))
def encrypt_plaintext(message: str, add_data: bytes, key: bytes) -> (bytes, bytes, bytes): """ Encrypt the payload of a packed message. Args: message: Message to encrypt add_data: key: Key used for encryption Returns: A tuple of (ciphertext, nonce, tag) """ nonce = pysodium.randombytes( pysodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES) message_bin = message.encode("ascii") output = pysodium.crypto_aead_chacha20poly1305_ietf_encrypt( message_bin, add_data, nonce, key) mlen = len(message) ciphertext = output[:mlen] tag = output[mlen:] return ciphertext, nonce, tag
# generate a random 64 bit nonce = pysodium.randombytes( pysodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES) assert pysodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES == 12 # write additional data into a single DER structure encoder = asn1.Encoder() encoder.start() encoder.enter(asn1.Numbers.Sequence) encoder.write(enckey, asn1.Numbers.OctetString) encoder.write(nonce, asn1.Numbers.OctetString) encoder.write(clargs.interval, asn1.Numbers.Integer) encoder.leave() AD = encoder.output() ctext = pysodium.crypto_aead_chacha20poly1305_ietf_encrypt( message=message.encode(), ad=AD, nonce=nonce, key=chachakey) # encode the whole contents, AD + ctext encoder = asn1.Encoder() encoder.start() encoder.enter(asn1.Numbers.Sequence) encoder.enter(asn1.Numbers.Sequence) encoder.write(enckey, asn1.Numbers.OctetString) encoder.write(nonce, asn1.Numbers.OctetString) encoder.write(clargs.interval, asn1.Numbers.Integer) encoder.leave() encoder.write(ctext, asn1.Numbers.OctetString) encoder.leave() DERmsg = encoder.output() print('-----BEGIN CHK ENCRYPTED MESSAGE-----')