def test_02_encrypt_decrypt_eas_base64(self): import os key = os.urandom(16) data = b"This is so secret!" s = aes_encrypt_b64(key, data) d = aes_decrypt_b64(key, s) self.assertEqual(data, d) otp_seed = os.urandom(20) s = aes_encrypt_b64(key, otp_seed) d = aes_decrypt_b64(key, s) self.assertEqual(otp_seed, d) otp_seed = os.urandom(32) s = aes_encrypt_b64(key, otp_seed) d = aes_decrypt_b64(key, s) self.assertEqual(otp_seed, d) # check some data generated with 2.23 hex_key = 'f84c2ddb09dee2a88194d5ac2156a8e4' data = b'secret data' enc_data = 'WNfUSNBNZF5kaPfujW8ueUi5Afas47pQ/3FHc3VymWM=' d = aes_decrypt_b64(binascii.unhexlify(hex_key), enc_data) self.assertEqual(data, d) enc_data = 'RDDvdAJhCnw/tlYscTxv+6idHAQnQFY5VpUK8SFflYQ=' d = aes_decrypt_b64(binascii.unhexlify(hex_key), enc_data) self.assertEqual(data, d)
def test_02_encrypt_decrypt_eas_base64(self): import os key = os.urandom(16) data = b"This is so secret!" s = aes_encrypt_b64(key, data) d = aes_decrypt_b64(key, s) self.assertEqual(data, d) otp_seed = os.urandom(20) s = aes_encrypt_b64(key, otp_seed) d = aes_decrypt_b64(key, s) self.assertEqual(otp_seed, d) otp_seed = os.urandom(32) s = aes_encrypt_b64(key, otp_seed) d = aes_decrypt_b64(key, s) self.assertEqual(otp_seed, d)
def test_02_encrypt_decrypt_eas_base64(self): import os key = os.urandom(16) data = "This is so secret!" s = aes_encrypt_b64(key, data) d = aes_decrypt_b64(key, s) self.assertEqual(data, d) otp_seed = os.urandom(20) s = aes_encrypt_b64(key, otp_seed) d = aes_decrypt_b64(key, s) self.assertEqual(otp_seed, d) otp_seed = os.urandom(32) s = aes_encrypt_b64(key, otp_seed) d = aes_decrypt_b64(key, s) self.assertEqual(otp_seed, d)
def export_pskc(tokenobj_list, psk=None): """ Take a list of token objects and create a beautifulsoup xml object. If no preshared key is given, we create one and return it. :param tokenobj_list: list of token objects :param psk: pre-shared-key for AES-128-CBC in hex format :return: tuple of (psk, number of tokens, beautifulsoup) """ if psk: psk = binascii.unhexlify(psk) else: psk = geturandom(16) mackey = geturandom(20) encrypted_mackey = aes_encrypt_b64(psk, mackey) number_of_exported_tokens = 0 # define the header soup = BeautifulSoup("""<KeyContainer Version="1.0" xmlns="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <EncryptionKey> <ds:KeyName>Pre-shared-key</ds:KeyName> </EncryptionKey> <MACMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"> <MACKey> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/> <xenc:CipherData> <xenc:CipherValue>{encrypted_mackey}</xenc:CipherValue> </xenc:CipherData> </MACKey> </MACMethod> """.format(encrypted_mackey=encrypted_mackey), "html.parser") for tokenobj in tokenobj_list: if tokenobj.type.lower() not in ["totp", "hotp", "pw"]: continue type = tokenobj.type.lower() issuer = "privacyIDEA" try: manufacturer = tokenobj.token.description.encode("ascii", "replace") manufacturer = to_unicode(manufacturer) except UnicodeEncodeError: manufacturer = "deleted during export" serial = tokenobj.token.serial otplen = tokenobj.token.otplen counter = tokenobj.token.count suite = tokenobj.get_tokeninfo("hashlib", default="sha1") if type == "totp": timestep = tokenobj.get_tokeninfo("timeStep") timedrift = tokenobj.get_tokeninfo("timeShift") else: timestep = 0 timedrift = 0 otpkey = tokenobj.token.get_otpkey().getKey() try: if tokenobj.type.lower() in ["totp", "hotp"]: encrypted_otpkey = aes_encrypt_b64(psk, binascii.unhexlify(otpkey)) elif tokenobj.type.lower() in ["pw"]: encrypted_otpkey = aes_encrypt_b64(psk, otpkey) else: encrypted_otpkey = aes_encrypt_b64(psk, otpkey) except TypeError: # Some keys might be odd string length continue try: kp2 = BeautifulSoup("""<KeyPackage> <DeviceInfo> <Manufacturer>{manufacturer}</Manufacturer> <SerialNo>{serial}</SerialNo> </DeviceInfo> <Key Id="{serial}" Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:{type}"> <Issuer>{issuer}</Issuer> <AlgorithmParameters> <ResponseFormat Length="{otplen}" Encoding="DECIMAL"/> <Suite hashalgo="{suite}" /> </AlgorithmParameters> <Data> <Secret> <EncryptedValue> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/> <xenc:CipherData> <xenc:CipherValue>{encrypted_otpkey}</xenc:CipherValue> </xenc:CipherData> </EncryptedValue> </Secret> <ValueMAC>TODOmissing</ValueMAC> <Time> <PlainValue>0</PlainValue> </Time> <TimeInterval> <PlainValue>{timestep}</PlainValue> </TimeInterval> <Counter> <PlainValue>{counter}</PlainValue> </Counter> <TimeDrift> <PlainValue>{timedrift}</PlainValue> </TimeDrift> </Data> </Key> </KeyPackage>""".format(serial=cgi.escape(serial), type=cgi.escape(type), otplen=otplen, issuer=cgi.escape(issuer), manufacturer=cgi.escape(manufacturer), counter=counter, timestep=timestep, encrypted_otpkey=encrypted_otpkey, timedrift=timedrift, suite=cgi.escape(suite)), "html.parser") soup.macmethod.insert_after(kp2) number_of_exported_tokens += 1 except Exception as e: log.warning(u"Failed to export the token {0!s}: {1!s}".format(serial, e)) tb = traceback.format_exc() log.debug(tb) return hexlify_and_unicode(psk), number_of_exported_tokens, soup
def export_pskc(tokenobj_list, psk=None): """ Take a list of token objects and create a beautifulsoup xml object. If no preshared key is given, we create one and return it. :param tokenobj_list: list of token objects :param psk: pre-shared-key for AES-128-CBC in hex format :return: tuple of (psk, number of tokens, beautifulsoup) """ if psk: psk = binascii.unhexlify(psk) else: psk = geturandom(16) mackey = geturandom(20) encrypted_mackey = aes_encrypt_b64(psk, mackey) number_of_exported_tokens = 0 # define the header soup = BeautifulSoup( """<KeyContainer Version="1.0" xmlns="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <EncryptionKey> <ds:KeyName>Pre-shared-key</ds:KeyName> </EncryptionKey> <MACMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"> <MACKey> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/> <xenc:CipherData> <xenc:CipherValue>{encrypted_mackey}</xenc:CipherValue> </xenc:CipherData> </MACKey> </MACMethod> """.format(encrypted_mackey=encrypted_mackey), "html.parser") for tokenobj in tokenobj_list: if tokenobj.type.lower() not in ["totp", "hotp", "pw"]: continue type = tokenobj.type.lower() issuer = "privacyIDEA" try: manufacturer = tokenobj.token.description.encode("ascii") except UnicodeEncodeError: manufacturer = "deleted during export" serial = tokenobj.token.serial otplen = tokenobj.token.otplen counter = tokenobj.token.count suite = tokenobj.get_tokeninfo("hashlib", default="sha1") if type == "totp": timestep = tokenobj.get_tokeninfo("timeStep") timedrift = tokenobj.get_tokeninfo("timeShift") else: timestep = 0 timedrift = 0 otpkey = tokenobj.token.get_otpkey().getKey() try: encrypted_otpkey = aes_encrypt_b64(psk, binascii.unhexlify(otpkey)) except TypeError: # Some keys might be odd string length continue try: kp2 = BeautifulSoup( """<KeyPackage> <DeviceInfo> <Manufacturer>{manufacturer}</Manufacturer> <SerialNo>{serial}</SerialNo> </DeviceInfo> <Key Id="{serial}" Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:{type}"> <Issuer>{issuer}</Issuer> <AlgorithmParameters> <ResponseFormat Length="{otplen}" Encoding="DECIMAL"/> <Suite hashalgo="{suite}" /> </AlgorithmParameters> <Data> <Secret> <EncryptedValue> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/> <xenc:CipherData> <xenc:CipherValue>{encrypted_otpkey}</xenc:CipherValue> </xenc:CipherData> </EncryptedValue> </Secret> <ValueMAC>TODOmissing</ValueMAC> <Time> <PlainValue>0</PlainValue> </Time> <TimeInterval> <PlainValue>{timestep}</PlainValue> </TimeInterval> <Counter> <PlainValue>{counter}</PlainValue> </Counter> <TimeDrift> <PlainValue>{timedrift}</PlainValue> </TimeDrift> </Data> </Key> </KeyPackage>""".format(serial=cgi.escape(serial), type=cgi.escape(type), otplen=otplen, issuer=cgi.escape(issuer), manufacturer=cgi.escape(manufacturer), counter=counter, timestep=timestep, encrypted_otpkey=encrypted_otpkey, timedrift=timedrift, suite=cgi.escape(suite)), "html.parser") soup.macmethod.insert_after(kp2) number_of_exported_tokens += 1 except Exception as e: log.warning(u"Failed to export the token {0!s}: {1!s}".format( serial, e)) return binascii.hexlify(psk), number_of_exported_tokens, soup
def export_pskc(tokenobj_list, psk=None): """ Take a list of token objects and create a beautifulsoup xml object. If no preshared key is given, we create one and return it. :param tokenobj_list: list of token objects :param psk: pre-shared-key for AES-128-CBC in hex format :return: tuple of (psk, beautifulsoup) """ import os if psk: psk = binascii.unhexlify(psk) else: psk = os.urandom(16) mackey = os.urandom(20) encrypted_mackey = aes_encrypt_b64(psk, mackey) # define the header soup = BeautifulSoup("""<KeyContainer Version="1.0" xmlns="urn:ietf:params:xml:ns:keyprov:pskc" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <EncryptionKey> <ds:KeyName>Pre-shared-key</ds:KeyName> </EncryptionKey> <MACMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"> <MACKey> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/> <xenc:CipherData> <xenc:CipherValue>{encrypted_mackey}</xenc:CipherValue> </xenc:CipherData> </MACKey> </MACMethod> """.format(encrypted_mackey=encrypted_mackey), "html.parser") for tokenobj in tokenobj_list: if tokenobj.type.lower() not in ["totp", "hotp"]: continue type = tokenobj.type.lower() issuer = "privacyIDEA" manufacturer = tokenobj.token.description serial = tokenobj.token.serial otplen = tokenobj.token.otplen counter = tokenobj.token.count suite = tokenobj.get_tokeninfo("hashlib", default="sha1") if type == "totp": timestep = tokenobj.get_tokeninfo("timeStep") else: timestep = 0 otpkey = tokenobj.token.get_otpkey().getKey() try: encrypted_otpkey = aes_encrypt_b64(psk, binascii.unhexlify(otpkey)) except TypeError: # Some keys might be odd string length continue kp2 = BeautifulSoup("""<KeyPackage> <DeviceInfo> <Manufacturer>{manufacturer}</Manufacturer> <SerialNo>{serial}</SerialNo> </DeviceInfo> <Key Id="{serial}" Algorithm="urn:ietf:params:xml:ns:keyprov:pskc:{type}"> <Issuer>{issuer}</Issuer> <AlgorithmParameters> <ResponseFormat Length="{otplen}" Encoding="DECIMAL"/> <Suite hashalgo="{suite}" /> </AlgorithmParameters> <Data> <Secret> <EncryptedValue> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/> <xenc:CipherData> <xenc:CipherValue>{encrypted_otpkey}</xenc:CipherValue> </xenc:CipherData> </EncryptedValue> </Secret> <ValueMAC>TODOmissing</ValueMAC> <Time> <PlainValue>0</PlainValue> </Time> <TimeInterval> <PlainValue>{timestep}</PlainValue> </TimeInterval> <Counter> {counter} </Counter> </Data> </Key> </KeyPackage>""".format(serial=serial, type=type, otplen=otplen, issuer=issuer, manufacturer=manufacturer, counter=counter, timestep=timestep, encrypted_otpkey=encrypted_otpkey, suite=suite), "html.parser") soup.macmethod.insert_after(kp2) return binascii.hexlify(psk), soup