Ejemplo n.º 1
0
    def test_initial_value_parameter(self):
        # Test with nonce parameter
        cipher1 = AES.new(self.key_128,
                          AES.MODE_CTR,
                          nonce=self.nonce_64,
                          initial_value=0xFFFF)
        counter = Counter.new(64, prefix=self.nonce_64, initial_value=0xFFFF)
        cipher2 = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        pt = get_tag_random("plaintext", 65536)
        self.assertEqual(cipher1.encrypt(pt), cipher2.encrypt(pt))

        # Test without nonce parameter
        cipher1 = AES.new(self.key_128, AES.MODE_CTR, initial_value=0xFFFF)
        counter = Counter.new(64, prefix=cipher1.nonce, initial_value=0xFFFF)
        cipher2 = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        pt = get_tag_random("plaintext", 65536)
        self.assertEqual(cipher1.encrypt(pt), cipher2.encrypt(pt))

        # Initial_value and Counter are mutually exclusive
        self.assertRaises(TypeError,
                          AES.new,
                          self.key_128,
                          AES.MODE_CTR,
                          counter=self.ctr_128,
                          initial_value=0)
Ejemplo n.º 2
0
 def initialize_cipher(self):
     """Creates the cipher-related objects needed for AES-CTR
     encryption and decryption.
     """
     self.ctr_e = Counter.new(self.AES_block_size, initial_value=self.iv)
     self.ctr_d = Counter.new(self.AES_block_size, initial_value=self.iv)
     self.encryptor = AES.new(self.key, AES.MODE_CTR, counter=self.ctr_e)
     self.decryptor = AES.new(self.key, AES.MODE_CTR, counter=self.ctr_d)
Ejemplo n.º 3
0
 def test_iv_with_matching_length(self):
     self.assertRaises(ValueError,
                       AES.new,
                       self.key_128,
                       AES.MODE_CTR,
                       counter=Counter.new(120))
     self.assertRaises(ValueError,
                       AES.new,
                       self.key_128,
                       AES.MODE_CTR,
                       counter=Counter.new(136))
Ejemplo n.º 4
0
    def write(self, path, data, offset, fh):
        if self.readonly:
            raise FuseOSError(errno.EPERM)
        # special check for special files
        if os.path.basename(path).startswith('.'):
            if windows:
                f = open(path, 'r+b', buffering=0)
                f.seek(offset)
                return f.write(data)
            else:
                with self.rwlock:
                    os.lseek(fh, offset, 0)
                    return os.write(fh, data)

        before = offset % 16
        # after = (offset + size) % 16
        counter = Counter.new(128,
                              initial_value=self.path_to_iv(path) +
                              (offset >> 4))
        cipher = AES.new(self.key, AES.MODE_CTR, counter=counter)
        out_data = cipher.decrypt((b'\0' * before) + data)[before:]
        if windows:
            with open(path, 'r+b', buffering=0) as f:
                f.seek(offset - before)
                written = f.write(out_data)
        else:
            with self.rwlock:
                os.lseek(fh, offset, 0)
                written = os.write(fh, out_data)

        return written
Ejemplo n.º 5
0
def Enc_first(cheque):
    key = get_random_bytes(32)
    salt = get_random_bytes(16)

    ctr = Counter.new(128, initial_value=bytes_to_long(salt))

    cipher = AES.new(key, AES.MODE_CTR, counter=ctr)

    cipher_text = cipher.encrypt(bytes(json.dumps(cheque), 'utf-8'))

    HMAC_FIRST = b"BBuXaXBdHg+wLPjRJpf3N/NmLq5kuvzGQx3II15/j8o="
    mk = hmac.new(b64decode(HMAC_FIRST), salt + cipher_text, hashlib.sha512)

    dataDE = b64encode(mk.digest() + salt + cipher_text).decode('utf-8')

    recipient_key = RSA.import_key(open('1RSAcert.pem').read())
    cipher_rsa = PKCS1_OAEP.new(recipient_key)
    dataAB = b64encode(cipher_rsa.encrypt(key)).decode('utf-8')

    # шифрованный запрос
    return {
        "ab": dataAB,
        "de": dataDE,
        "kassaid": "122772",
        "kassatoken": "5373167af64a6e02cae10c2bf5c6a7e4",
        "check_type": "standart",
        "test": "0"
    }
Ejemplo n.º 6
0
    def decrypt(self, init_value, ciphertext, auth_tag, auth_data=b''):
        if init_value >= (1 << 96):
            raise InvalidInputException('IV should be 96-bit')
        if auth_tag >= (1 << 128):
            raise InvalidInputException('Tag should be 128-bit')

        if auth_tag != self.__ghash(
                auth_data, ciphertext) ^ bytes_to_long(
            self._aes_ecb.encrypt(
                long_to_bytes((init_value << 32) | 1, 16))):
            raise InvalidTagException

        len_ciphertext = len(ciphertext)
        if len_ciphertext > 0:
            counter = Counter.new(
                nbits=32,
                prefix=long_to_bytes(init_value, 12),
                initial_value=2,
                allow_wraparound=True)
            aes_ctr = AES.new(self._master_key, AES.MODE_CTR, counter=counter)

            if 0 != len_ciphertext % 16:
                padded_ciphertext = ciphertext + \
                                    b'\x00' * (16 - len_ciphertext % 16)
            else:
                padded_ciphertext = ciphertext
            plaintext = aes_ctr.decrypt(padded_ciphertext)[:len_ciphertext]

        else:
            plaintext = b''

        return plaintext
    def create_ephIDs(SK):
        ''' Create the set of beacons for the day based on a new SK_t.

			This method created the set of ephemeral IDs given an SK for
			day / broadcast_key.

			Arguments:
				SK(b[]): given SK (b"rand" * 32)

			Returns:
				[b[]]: Set of ephemeral IDs (ephIDs) for a single day.
		'''
        # Set up PRF with the SK and broadcast_key
        prf = hmac.new(SK, BROADCAST_KEY.encode(), hashlib.sha256).digest()
        # Start with a fresh counter each day and initialize AES in CTR mode
        prg = AES.new(prf,
                      AES.MODE_CTR,
                      counter=Counter.new(128, initial_value=0))
        ephIDs = []

        # Create the number of desired ephIDs by encrypting 0 bytes
        prg_data = prg.encrypt(b"\0" * 16 * NUM_EPOCHS_PER_DAY)
        for i in range(NUM_EPOCHS_PER_DAY):
            # split the prg data into individual ephIDs
            ephIDs.append(prg_data[i * 16:i * 16 + 16])
        return ephIDs
Ejemplo n.º 8
0
    def create_ctr_cipher(self, keyslot: Keyslot,
                          ctr: int) -> 'Union[CtrMode, _TWLCryptoWrapper]':
        """
        Create an AES-CTR cipher with the given keyslot.

        Normal and DSi crypto will be automatically chosen depending on keyslot.

        :param keyslot: :class:`Keyslot` to use.
        :param ctr: Counter to start with.
        :return: An AES-CTR cipher object from PyCryptodome, or a wrapper for DSi keyslots.
        :rtype: CtrMode | _TWLCryptoWrapper
        """
        try:
            key = self.key_normal[keyslot]
        except KeyError:
            raise KeyslotMissingError(
                f'normal key for keyslot 0x{keyslot:02x} is not set up')

        cipher = AES.new(key,
                         AES.MODE_CTR,
                         counter=Counter.new(128, initial_value=ctr))

        if keyslot < 0x04:
            return _TWLCryptoWrapper(cipher)
        else:
            return cipher
Ejemplo n.º 9
0
def decrypt(password, data):
    '''
    Decrypt some data.  Input must be bytes.

    @param password: The secret value used as the basis for a key.
    This should be as long as varied as possible.  Try to avoid common words.

    @param data: The data to be decrypted, typically as bytes.

    @return: The decrypted data, as bytes.  If the original message was a
    string you can re-create that using `result.decode('utf8')`.
    '''
    _assert_not_unicode(data)
    _assert_header_prefix(data)
    version = _assert_header_version(data)
    _assert_decrypt_length(data, version)
    raw = data[HEADER_LEN:]
    salt = raw[:SALT_LEN[version] // 8]
    hmac_key, cipher_key = _expand_keys(password, salt,
                                        EXPANSION_COUNT[version])
    hmac = raw[-HASH.digest_size:]
    hmac2 = _hmac(hmac_key, data[:-HASH.digest_size])
    _assert_hmac(hmac_key, hmac, hmac2)
    counter = Counter.new(HALF_BLOCK, prefix=salt[:HALF_BLOCK // 8])
    cipher = AES.new(cipher_key, AES.MODE_CTR, counter=counter)
    return cipher.decrypt(raw[SALT_LEN[version] // 8:-HASH.digest_size])
Ejemplo n.º 10
0
    def decrypt(self, init_value, ciphertext, auth_tag, auth_data=b''):
        if init_value >= (1 << 96):
            raise InvalidInputException('IV should be 96-bit')
        if auth_tag >= (1 << 128):
            raise InvalidInputException('Tag should be 128-bit')

        if auth_tag != self.__ghash(auth_data, ciphertext) ^ bytes_to_long(
                self._aes_ecb.encrypt(long_to_bytes(
                    (init_value << 32) | 1, 16))):
            raise InvalidTagException

        len_ciphertext = len(ciphertext)
        if len_ciphertext > 0:
            counter = Counter.new(nbits=32,
                                  prefix=long_to_bytes(init_value, 12),
                                  initial_value=2,
                                  allow_wraparound=True)
            aes_ctr = AES.new(self._master_key, AES.MODE_CTR, counter=counter)

            if 0 != len_ciphertext % 16:
                padded_ciphertext = ciphertext + \
                                    b'\x00' * (16 - len_ciphertext % 16)
            else:
                padded_ciphertext = ciphertext
            plaintext = aes_ctr.decrypt(padded_ciphertext)[:len_ciphertext]

        else:
            plaintext = b''

        return plaintext
Ejemplo n.º 11
0
def generate_ephids_for_day(current_day_key, shuffle=True):
    """Generates the list of EphIDs for the current day

    Args:
        key (byte array): A 32-byte key
        shuffle (bool, optional): Whether to shuffle the list of EphIDs. Default: True.
            Should only be set to False when testing or when generating test vectors

    Returns:
        list of byte arrays: The list of EphIDs for the day
    """

    # Compute key for stream cipher based on current_day_key
    stream_key = hmac.new(current_day_key, BROADCAST_KEY,
                          hashlib.sha256).digest()

    # Start with a fresh counter each day and initialize AES in CTR mode
    counter = Counter.new(128, initial_value=0)
    prg = AES.new(stream_key, AES.MODE_CTR, counter=counter)

    # Create the number of desired ephIDs by drawing from AES in CTR mode
    # operating a s a stream cipher. To get the raw output, we ask the library
    # to "encrypt" an all-zero message of sufficient length.
    prg_output_bytes = prg.encrypt(bytes(LENGTH_EPHID * NUM_EPOCHS_PER_DAY))

    ephids = [
        prg_output_bytes[idx:idx + LENGTH_EPHID]
        for idx in range(0, len(prg_output_bytes), LENGTH_EPHID)
    ]

    # Shuffle the resulting ephids
    if shuffle:
        secure_shuffle(ephids)

    return ephids
Ejemplo n.º 12
0
    def read(self, path, size, offset, fh):
        # special check for special files
        if os.path.basename(path).startswith('.'):
            if windows:
                f = open(path, 'rb', buffering=0)
                f.seek(offset)
                return f.read(size)
            else:
                with self.rwlock:
                    os.lseek(fh, offset, 0)
                    return os.read(fh, size)

        before = offset % 16
        after = (offset + size) % 16
        # size_fix = size
        # if size % 16 != 0:
        #     size_fix = size + 16 - size % 16
        if windows:
            with open(path, 'rb', buffering=0) as f:
                f.seek(offset - before)
                data = f.read(size)
        else:
            with self.rwlock:
                os.lseek(fh, offset - before, 0)
                data = os.read(fh, size)
        counter = Counter.new(128,
                              initial_value=self.path_to_iv(path) +
                              (offset >> 4))
        cipher = AES.new(self.key, AES.MODE_CTR, counter=counter)
        out_data = cipher.decrypt(data)[before:]
        return out_data
Ejemplo n.º 13
0
def get_DES(key, mode):
    # возвращает класс DES
    if mode == DES.MODE_CTR:
        print("Create counter")
        counter = Counter.new(nbits=64)
        return DES.new(key, mode, counter=counter)
    return DES.new(key, mode)
Ejemplo n.º 14
0
    async def _encrypt_media(
        self,
        data: AsyncIterator[bytes],
    ) -> AsyncIterator[Union[bytes, EncryptedMediaInfo]]:

        aes256_key = Random.new().read(32)
        init_vector = Random.new().read(8)
        counter = Counter.new(64, prefix=init_vector, initial_value=0)
        cipher = AES.new(aes256_key, AES.MODE_CTR, counter=counter)
        sha256 = SHA256.new()

        async for chunk in data:
            encrypted = cipher.encrypt(chunk)
            sha256.update(encrypted)
            yield encrypted

        yield EncryptedMediaInfo(
            mxc=MXC("mxc://replace/me"),
            init_vector=encode_base64(init_vector + b"\x00" * 8),
            key=encode_base64(aes256_key, urlsafe=True),
            sha256=encode_base64(sha256.digest()),
            key_operations=["encrypt", "decrypt"],
            key_type="oct",
            key_algorithm="A256CTR",
            key_extractable=True,
            version="v2",
        )
Ejemplo n.º 15
0
def decrypt(key):
    if check_key(key):
        l = tkinter.Label(
            root,
            text="This is the correct key. \n"
            "Your files are being decrypted but it may take a while. Please wait..."
        )
        l.pack()
        ctr = Counter.new(128)
        crypt = AES.new(key.encode(), AES.MODE_CTR, counter=ctr)
        startdirs = START_DIR
        for currentDir in startdirs:
            for file in discover.discoverFiles(currentDir):
                (name, ext) = os.path.splitext(file)
                if ext in '.Cryptsky':
                    try:
                        modify.modify_file_inplace(file, crypt.encrypt)
                        os.rename(file, name)
                    except IOError:
                        print("Error")
        try:
            print()
            os.remove(r'C:\Windows\Temp\winUpdater.log')
        except FileNotFoundError:
            pass
        label = tkinter.Label(
            root, text="Congratulations. Your files are now decrypted")
        label.pack()
    else:
        return False
Ejemplo n.º 16
0
    async def _decrypt_media(
        self,
        data: AsyncIterator[bytes],
        info: EncryptedMediaInfo,
    ) -> AsyncIterator[bytes]:

        try:
            wanted_sha256 = decode_base64(info.sha256)
            aes256_key = decode_base64(info.key)
            init_vector = decode_base64(info.init_vector)
        except BinAsciiError as e:
            raise err.MediaInvalidBase64(next(iter(e.args), ""))

        sha256 = SHA256.new()
        prefix = init_vector[:8]
        init_value = int.from_bytes(init_vector[8:], "big")
        counter = Counter.new(64, prefix=prefix, initial_value=init_value)

        try:
            cipher = AES.new(aes256_key, AES.MODE_CTR, counter=counter)
        except ValueError as e:
            raise err.MediaAESError(next(iter(e.args), ""))

        async for chunk in data:
            sha256.update(chunk)
            yield cipher.decrypt(chunk)

        got_sha256 = sha256.digest()

        if wanted_sha256 != got_sha256:
            raise err.MediaSHA256Mismatch(wanted_sha256, got_sha256)
Ejemplo n.º 17
0
def extract_files(wak, out_dir, extract=True):
    if extract:
        out_dir = out_dir + "/"
        print("[+] Extracting to {}".format(out_dir))
        if not os.path.exists(out_dir):
            os.makedirs(out_dir)

    # multiprocessing this
    for f in wak.file_list:
        print("{:.50s}:[offs {:08X}][size {:08X}][pthl {:08X}]".format(
            f.path, f.offset, f.size, f.pathlen))
        if extract:
            fdata = wak.datawak_contents[f.offset:f.offset + f.size]
            f_iv = wak.prng.badprng_get16(0x165EC8F + f.tblidx)

            c = Counter.new(128, initial_value=bytes_to_long(f_iv))
            fdata_dec = AES.new(wak.prng.default_key, AES.MODE_CTR,
                                counter=c).decrypt(fdata)

            out_filepath = os.path.abspath(out_dir + f.path)
            out_filedir = os.path.split(out_filepath)[0]
            if not os.path.exists(out_filedir):
                os.makedirs(out_filedir)
            with open(out_filepath, 'wb') as outfile:
                outfile.write(fdata_dec)
    print("[+] Complete, iterated {} files.".format(len(wak.file_list)))
Ejemplo n.º 18
0
def decrypt_ctr(key, cypherText):
    iv = cypherText[:block_size]
    ct1 = cypherText[block_size:]
    ctr = Counter.new(block_size * 8, initial_value=int(codecs.encode(iv, 'hex'), 16))
    obj = AES.new(key, AES.MODE_CTR, counter=ctr)
    padded_str = obj.decrypt(ct1)
    return padded_str
Ejemplo n.º 19
0
    def test_nonce_parameter(self):
        # Nonce parameter becomes nonce attribute
        cipher1 = AES.new(self.key_128, AES.MODE_CTR, nonce=self.nonce_64)
        self.assertEqual(cipher1.nonce, self.nonce_64)

        counter = Counter.new(64, prefix=self.nonce_64, initial_value=0)
        cipher2 = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        self.assertEqual(cipher1.nonce, cipher2.nonce)

        pt = get_tag_random("plaintext", 65536)
        self.assertEqual(cipher1.encrypt(pt), cipher2.encrypt(pt))

        # Nonce is implicitly created (for AES) when no parameters are passed
        nonce1 = AES.new(self.key_128, AES.MODE_CTR).nonce
        nonce2 = AES.new(self.key_128, AES.MODE_CTR).nonce
        self.assertNotEqual(nonce1, nonce2)
        self.assertEqual(len(nonce1), 8)

        # Nonce can be zero-length
        cipher = AES.new(self.key_128, AES.MODE_CTR, nonce=b(""))
        self.assertEqual(b(""), cipher.nonce)

        # Nonce and Counter are mutually exclusive
        self.assertRaises(TypeError,
                          AES.new,
                          self.key_128,
                          AES.MODE_CTR,
                          counter=self.ctr_128,
                          nonce=self.nonce_64)
Ejemplo n.º 20
0
def get_each_aes(bytes_data, bytes_key, bytes_iv):
    results = []
    # ECB
    res = AES.new(bytes_key, AES.MODE_ECB).encrypt(bytes_data)
    results.append(("ECB", res))

    # no iv CTR
    res = AES.new(bytes_key, AES.MODE_CTR).encrypt(bytes_data)
    results.append(("CTR", res))

    c = Counter.new(128, initial_value=bytes_to_long(bytes_iv))
    res = AES.new(bytes_key, AES.MODE_CTR, counter=c).encrypt(bytes_data)
    results.append(("CTR-iv", res))

    res = AES.new(bytes_key, AES.MODE_CBC, bytes_iv).encrypt(bytes_data)
    results.append(("CBC", res))

    res = AES.new(bytes_key, AES.MODE_CFB, bytes_iv).encrypt(bytes_data)
    results.append(("CFB", res))

    res = AES.new(bytes_key, AES.MODE_OFB, bytes_iv).encrypt(bytes_data)
    results.append(("OFB", res))

    res = AES.new(bytes_key, AES.MODE_GCM, bytes_iv).encrypt(bytes_data)
    results.append(("GCM", res))

    # SIV keylen is restricted. prob not SIV.
    #    res = AES.new(bytes_key, AES.MODE_SIV, bytes_iv).encrypt(bytes_data)
    #    results.append(("SIV", res))

    # OCB takes a 15 byte nonce. don't think so.
    #    res = AES.new(bytes_key, AES.MODE_OCB, bytes_iv).encrypt(bytes_data)
    #    results.append(("OCB", res))

    return results
Ejemplo n.º 21
0
    def test_nonce_parameter(self):
        # Nonce parameter becomes nonce attribute
        cipher1 = AES.new(self.key_128, AES.MODE_CTR, nonce=self.nonce_64)
        self.assertEqual(cipher1.nonce, self.nonce_64)

        counter = Counter.new(64, prefix=self.nonce_64, initial_value=0)
        cipher2 = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        self.assertEqual(cipher1.nonce, cipher2.nonce)

        pt = get_tag_random("plaintext", 65536)
        self.assertEqual(cipher1.encrypt(pt), cipher2.encrypt(pt))

        # Nonce is implicitly created (for AES) when no parameters are passed
        nonce1 = AES.new(self.key_128, AES.MODE_CTR).nonce
        nonce2 = AES.new(self.key_128, AES.MODE_CTR).nonce
        self.assertNotEqual(nonce1, nonce2)
        self.assertEqual(len(nonce1), 8)

        # Nonce can be zero-length
        cipher = AES.new(self.key_128, AES.MODE_CTR, nonce=b"")
        self.assertEqual(b"", cipher.nonce)
        cipher.encrypt(b'0'*300)

        # Nonce and Counter are mutually exclusive
        self.assertRaises(TypeError, AES.new, self.key_128, AES.MODE_CTR,
                          counter=self.ctr_128, nonce=self.nonce_64)
Ejemplo n.º 22
0
def mfa_decrypt_backup_tokens(backup_secret, file):
    """ Decrypts backed up MFA secrets from file, prints to stdout. """
    with open(os.path.expanduser(file), 'r') as infile:
        data = infile.read()
    counter = Counter.new(128, initial_value=1337)
    cipher = AES.new(get_backup_key_digest(backup_secret),
                     AES.MODE_CTR,
                     counter=counter)
    return cipher.decrypt(base64.b64decode(data)).decode()
Ejemplo n.º 23
0
 def __init__(self, key):
     self.key = key
     self.counter = Counter.new(128)
     if len(self.key) != 32:
         print("AES KEY ERROR, CIPHER INSECURE")
         print("REPORT THIS ERROR")
         print("YOU SHOULD ****NEVER**** SEE THIS")
         quit()
     self.aes_cipher = AES.new(self.key, AES.MODE_CTR, counter=self.counter)
Ejemplo n.º 24
0
def encrypt(n, key, data):
    sha256 = hashlib.sha256()
    sha256.update(key)
    digest = sha256.digest()
    key = digest[:16]
    print((n, [c for c in key], [c for c in data]))
    aes = AES.new(key, AES.MODE_CTR, counter=Counter.new(128, initial_value=n))
    encrypted = aes.encrypt(data)
    return base64.b64encode(encrypted).decode()
Ejemplo n.º 25
0
def decrypt(key, inp, out):
    """
    decrypt()

    @param key: AES-128 CENC key in bytes
    @param inp: Open input file
    @param out: Open output file
    """

    with BufferedReader(inp) as reader:
        senc_boxes = deque()
        trun_boxes = deque()

        while reader.peek(1):
            box = Box.parse_stream(reader)
            fix_headers(box)

            for stsd_box in BoxUtil.find(box, b'stsz'):
                sample_size = stsd_box.sample_size

            if box.type == b'moof':
                senc_boxes.extend(BoxUtil.find(box, b'senc'))
                trun_boxes.extend(BoxUtil.find(box, b'trun'))
            elif box.type == b'mdat':
                senc_box = senc_boxes.popleft()
                trun_box = trun_boxes.popleft()

                clear_box = b''

                with BytesIO(box.data) as box_bytes:
                    for sample, sample_info in zip(
                            senc_box.sample_encryption_info,
                            trun_box.sample_info):
                        counter = Counter.new(64,
                                              prefix=sample.iv,
                                              initial_value=0)

                        cipher = AES.new(key, AES.MODE_CTR, counter=counter)

                        if sample_size:
                            cipher_bytes = box_bytes.read(sample_size)
                            clear_box += cipher.decrypt(cipher_bytes)
                        elif not sample.subsample_encryption_info:
                            cipher_bytes = box_bytes.read(
                                sample_info.sample_size)
                            clear_box += cipher.decrypt(cipher_bytes)
                        else:
                            for subsample in sample.subsample_encryption_info:
                                clear_box += box_bytes.read(
                                    subsample.clear_bytes)
                                cipher_bytes = box_bytes.read(
                                    subsample.cipher_bytes)
                                clear_box += cipher.decrypt(cipher_bytes)
                box.data = clear_box
            out.write(Box.build(box))
    return
Ejemplo n.º 26
0
    def test_wrap_around(self):
        counter = Counter.new(8, prefix=bchr(9) * 15)

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        cipher.encrypt(bchr(9) * 16 * 255)
        self.assertRaises(OverflowError, cipher.encrypt, bchr(9) * 16)

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        cipher.decrypt(bchr(9) * 16 * 255)
        self.assertRaises(OverflowError, cipher.decrypt, bchr(9) * 16)
Ejemplo n.º 27
0
    def test_wrap_around(self):
        counter = Counter.new(8, prefix=bchr(9) * 15)

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        cipher.encrypt(bchr(9) * 16 * 255)
        self.assertRaises(OverflowError, cipher.encrypt, bchr(9) * 16)

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        cipher.decrypt(bchr(9) * 16 * 255)
        self.assertRaises(OverflowError, cipher.decrypt, bchr(9) * 16)
Ejemplo n.º 28
0
    def test_initial_value_parameter(self):
        # Test with nonce parameter
        cipher1 = AES.new(self.key_128, AES.MODE_CTR,
                          nonce=self.nonce_64, initial_value=0xFFFF)
        counter = Counter.new(64, prefix=self.nonce_64, initial_value=0xFFFF)
        cipher2 = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        pt = get_tag_random("plaintext", 65536)
        self.assertEqual(cipher1.encrypt(pt), cipher2.encrypt(pt))

        # Test without nonce parameter
        cipher1 = AES.new(self.key_128, AES.MODE_CTR,
                          initial_value=0xFFFF)
        counter = Counter.new(64, prefix=cipher1.nonce, initial_value=0xFFFF)
        cipher2 = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        pt = get_tag_random("plaintext", 65536)
        self.assertEqual(cipher1.encrypt(pt), cipher2.encrypt(pt))

        # Initial_value and Counter are mutually exclusive
        self.assertRaises(TypeError, AES.new, self.key_128, AES.MODE_CTR,
                          counter=self.ctr_128, initial_value=0)
Ejemplo n.º 29
0
def decryption(key, file_name):
    counter = Counter.new(128)
    d = AES.new(key, AES.MODE_CTR, counter=counter)
    with open(file_name, 'r+b') as f:
        block_size = 16
        plaintext = f.read(block_size)
        while plaintext:
            f.seek(-len(plaintext), 1)
            f.write(d.decrypt(plaintext))
            plaintext = f.read(block_size)
    os.rename(file_name, file_name.strip(".R"))
Ejemplo n.º 30
0
    def prepare_decoder(self, offset):
        initial_value = self.initial_value + int(offset / 16)
        try:
            from Cryptodome.Cipher import AES
            from Cryptodome.Util import Counter
            self.decryptor = AES.new(self._file._client.a32_to_str(self.k),
                                     AES.MODE_CTR,
                                     counter=Counter.new(
                                         128, initial_value=initial_value))
        except:
            from Crypto.Cipher import AES
            from Crypto.Util import Counter
            self.decryptor = AES.new(self._file._client.a32_to_str(self.k),
                                     AES.MODE_CTR,
                                     counter=Counter.new(
                                         128, initial_value=initial_value))

        rest = offset - int(offset / 16) * 16
        if rest:
            self.decode(str(0) * rest)
Ejemplo n.º 31
0
def rclone_encrypt_password(password):
    key = bytes([0x9c, 0x93, 0x5b, 0x48, 0x73, 0x0a, 0x55, 0x4d,
                 0x6b, 0xfd, 0x7c, 0x63, 0xc8, 0x86, 0xa9, 0x2b,
                 0xd3, 0x90, 0x19, 0x8e, 0xb8, 0x12, 0x8a, 0xfb,
                 0xf4, 0xde, 0x16, 0x2b, 0x8b, 0x95, 0xf6, 0x38])

    iv = Random.new().read(AES.block_size)
    counter = Counter.new(128, initial_value=int(codecs.encode(iv, "hex"), 16))
    cipher = AES.new(key, AES.MODE_CTR, counter=counter)
    encrypted = iv + cipher.encrypt(password.encode("utf-8"))
    return base64.urlsafe_b64encode(encrypted).decode("ascii").rstrip("=")
Ejemplo n.º 32
0
    def decrypt(self, text: bytes):
        """
        解密函数
        :param text:
        :return:
        """
        text = base64.b64decode(text)
        countf = Counter.new(64, text[:8])

        encrypto = AES.new(self.key, AES.MODE_CTR, counter=countf)
        plain_text = encrypto.decrypt(text[8:])
        return plain_text.decode().rstrip('\0')
Ejemplo n.º 33
0
    def test_nonce_attribute(self):
        # Nonce attribute is the prefix passed to Counter (DES3)
        cipher = DES3.new(self.key_192, DES3.MODE_CTR, counter=self.ctr_64)
        self.assertEqual(cipher.nonce, self.nonce_32)

        # Nonce attribute is the prefix passed to Counter (AES)
        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=self.ctr_128)
        self.assertEqual(cipher.nonce, self.nonce_64)

        # Nonce attribute is not defined if suffix is used in Counter
        counter = Counter.new(64, prefix=self.nonce_32, suffix=self.nonce_32)
        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        self.failIf(hasattr(cipher, "nonce"))
Ejemplo n.º 34
0
def encrypt(data):
    data = data.encode('utf8')

    def pad(x):
        return x + (PWENC_BLOCK_SIZE -
                    len(x) % PWENC_BLOCK_SIZE) * PWENC_PADDING

    nonce = os.urandom(8)
    cipher = AES.new(PWEncService.get_secret(),
                     AES.MODE_CTR,
                     counter=Counter.new(64, prefix=nonce))
    encoded = base64.b64encode(nonce + cipher.encrypt(pad(data)))
    return encoded.decode()
Ejemplo n.º 35
0
    def test_nonce_attribute(self):
        # Nonce attribute is the prefix passed to Counter (DES3)
        cipher = DES3.new(self.key_192, DES3.MODE_CTR, counter=self.ctr_64)
        self.assertEqual(cipher.nonce, self.nonce_32)

        # Nonce attribute is the prefix passed to Counter (AES)
        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=self.ctr_128)
        self.assertEqual(cipher.nonce, self.nonce_64)

        # Nonce attribute is not defined if suffix is used in Counter
        counter = Counter.new(64, prefix=self.nonce_32, suffix=self.nonce_32)
        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        self.failIf(hasattr(cipher, "nonce"))
Ejemplo n.º 36
0
    def test_wrap_around(self):
        # Counter is only 8 bits, so we can only encrypt/decrypt 256 blocks (=4096 bytes)
        counter = Counter.new(8, prefix=bchr(9) * 15)
        max_bytes = 4096

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        cipher.encrypt(b'9' * max_bytes)
        self.assertRaises(OverflowError, cipher.encrypt, b'9')

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        self.assertRaises(OverflowError, cipher.encrypt, b'9' * (max_bytes + 1))

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        cipher.decrypt(b'9' * max_bytes)
        self.assertRaises(OverflowError, cipher.decrypt, b'9')

        cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter)
        self.assertRaises(OverflowError, cipher.decrypt, b'9' * (max_bytes + 1))
Ejemplo n.º 37
0
    def test_aes_256(self):
        plaintext =     '6bc1bee22e409f96e93d7e117393172a' +\
                        'ae2d8a571e03ac9c9eb76fac45af8e51' +\
                        '30c81c46a35ce411e5fbc1191a0a52ef' +\
                        'f69f2445df4f9b17ad2b417be66c3710'
        ciphertext =    '601ec313775789a5b7a7f504bbf3d228' +\
                        'f443e3ca4d62b59aca84e990cacaf5c5' +\
                        '2b0930daa23de94ce87017ba2d84988d' +\
                        'dfc9c58db67aada613c2dd08457941a6'
        key =           '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4'
        counter =       Counter.new(nbits=16,
                                    prefix=unhexlify('f0f1f2f3f4f5f6f7f8f9fafbfcfd'),
                                    initial_value=0xfeff)
        key = unhexlify(key)
        plaintext = unhexlify(plaintext)
        ciphertext = unhexlify(ciphertext)

        cipher = AES.new(key, AES.MODE_CTR, counter=counter)
        self.assertEqual(cipher.encrypt(plaintext), ciphertext)
        cipher = AES.new(key, AES.MODE_CTR, counter=counter)
        self.assertEqual(cipher.decrypt(ciphertext), plaintext)
Ejemplo n.º 38
0
    def test_aes_192(self):
        plaintext =     '6bc1bee22e409f96e93d7e117393172a' +\
                        'ae2d8a571e03ac9c9eb76fac45af8e51' +\
                        '30c81c46a35ce411e5fbc1191a0a52ef' +\
                        'f69f2445df4f9b17ad2b417be66c3710'
        ciphertext =    '1abc932417521ca24f2b0459fe7e6e0b' +\
                        '090339ec0aa6faefd5ccc2c6f4ce8e94' +\
                        '1e36b26bd1ebc670d1bd1d665620abf7' +\
                        '4f78a7f6d29809585a97daec58c6b050'
        key =           '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b'
        counter =       Counter.new(nbits=16,
                                    prefix=unhexlify('f0f1f2f3f4f5f6f7f8f9fafbfcfd'),
                                    initial_value=0xfeff)

        key = unhexlify(key)
        plaintext = unhexlify(plaintext)
        ciphertext = unhexlify(ciphertext)

        cipher = AES.new(key, AES.MODE_CTR, counter=counter)
        self.assertEqual(cipher.encrypt(plaintext), ciphertext)
        cipher = AES.new(key, AES.MODE_CTR, counter=counter)
        self.assertEqual(cipher.decrypt(ciphertext), plaintext)
Ejemplo n.º 39
0
    def test_aes_128(self):
        plaintext =     '6bc1bee22e409f96e93d7e117393172a' +\
                        'ae2d8a571e03ac9c9eb76fac45af8e51' +\
                        '30c81c46a35ce411e5fbc1191a0a52ef' +\
                        'f69f2445df4f9b17ad2b417be66c3710'
        ciphertext =    '874d6191b620e3261bef6864990db6ce' +\
                        '9806f66b7970fdff8617187bb9fffdff' +\
                        '5ae4df3edbd5d35e5b4f09020db03eab' +\
                        '1e031dda2fbe03d1792170a0f3009cee'
        key =           '2b7e151628aed2a6abf7158809cf4f3c'
        counter =       Counter.new(nbits=16,
                                    prefix=unhexlify('f0f1f2f3f4f5f6f7f8f9fafbfcfd'),
                                    initial_value=0xfeff)

        key = unhexlify(key)
        plaintext = unhexlify(plaintext)
        ciphertext = unhexlify(ciphertext)

        cipher = AES.new(key, AES.MODE_CTR, counter=counter)
        self.assertEqual(cipher.encrypt(plaintext), ciphertext)
        cipher = AES.new(key, AES.MODE_CTR, counter=counter)
        self.assertEqual(cipher.decrypt(ciphertext), plaintext)
Ejemplo n.º 40
0
    def encrypt(self, init_value, plaintext, auth_data=b''):
        if init_value >= (1 << 96):
            raise InvalidInputException('IV should be 96-bit')
        # a naive checking for IV reuse
        if init_value == self.prev_init_value:
            raise InvalidInputException('IV must not be reused!')
        self.prev_init_value = init_value

        len_plaintext = len(plaintext)
        # len_auth_data = len(auth_data)

        if len_plaintext > 0:
            counter = Counter.new(
                nbits=32,
                prefix=long_to_bytes(init_value, 12),
                initial_value=2,  # notice this
                allow_wraparound=True)
            aes_ctr = AES.new(self._master_key, AES.MODE_CTR, counter=counter)

            if 0 != len_plaintext % 16:
                padded_plaintext = plaintext + \
                                   b'\x00' * (16 - len_plaintext % 16)
            else:
                padded_plaintext = plaintext
            ciphertext = aes_ctr.encrypt(padded_plaintext)[:len_plaintext]

        else:
            ciphertext = b''

        auth_tag = self.__ghash(auth_data, ciphertext)
        # print 'GHASH\t', hex(auth_tag)
        auth_tag ^= bytes_to_long(self._aes_ecb.encrypt(
            long_to_bytes((init_value << 32) | 1, 16)))

        # assert len(ciphertext) == len(plaintext)
        assert auth_tag < (1 << 128)
        return ciphertext, auth_tag
 def test_iv(self):
     c = Counter.new(128, initial_value=2)
Ejemplo n.º 42
0
 def generate_counter(cls, block_size, iv):
     ctr = Counter.new(block_size * 8,
                       initial_value=int(binascii.hexlify(iv), 16))
     return ctr
Ejemplo n.º 43
0
    def decrypt_and_verify_challenge(self, challenge_url, action):

        """
        Decrypts the data packed in the challenge url, verifies
        its content, returns the parsed data as a dictionary,
        calculates and returns the signature.

        The calling method must then send the signature
        back to the server. (The reason for this control flow
        is that the challenge data must be checked in different
        scenarios, e.g. when we have a pairing the data must be
        checked by the method that simulates the pairing)

        :param challenge_url: the challenge url as sent by the server
        :param action: a string identifier for the verification action
            (at the moment 'ACCEPT' or 'DENY')

        :returns: (challenge, signature)

            challenge has the keys

                * content_type - one of the three values CONTENT_TYPE_SIGNREQ,
                    CONTENT_TYPE_PAIRING or CONTENT_TYPE_LOGIN)
                    (all defined in this module)
                * transaction_id - used to identify the challenge
                    on the server
                * callback_url (optional) - the url to which the challenge
                    response should be set
                * user_token_id - used to identify the token in the
                    user database for which this challenge was created

            depending on the content type additional keys are present

                * for CONTENT_TYPE_PAIRING: serial
                * for CONTENT_TYPE_SIGNREQ: message
                * for CONTENT_TYPE_LOGIN: login, host

            signature is the generated user signature used to
            respond to the challenge
        """

        challenge_data_encoded = challenge_url[len(self.uri + '://chal/'):]
        challenge_data = decode_base64_urlsafe(challenge_data_encoded)

        # ------------------------------------------------------------------ --

        # parse and verify header information in the
        # encrypted challenge data

        header = challenge_data[0:5]
        version, user_token_id = struct.unpack('<bI', header)
        self.assertEqual(version, CHALLENGE_URL_VERSION)

        # ------------------------------------------------------------------ --

        # get token from client token database

        token = self.tokens[user_token_id]
        server_public_key = token['server_public_key']

        # ------------------------------------------------------------------ --

        # prepare decryption by seperating R from
        # ciphertext and server signature

        R = challenge_data[5:5 + 32]
        ciphertext = challenge_data[5 + 32:-64]
        server_signature = challenge_data[-64:]

        # check signature

        data = challenge_data[0:-64]
        crypto_sign_verify_detached(server_signature, data, server_public_key)

        # ------------------------------------------------------------------ --

        # key derivation

        secret_key_dh = dsa_to_dh_secret(self.secret_key)
        ss = calc_dh(secret_key_dh, R)
        U = SHA256.new(ss).digest()

        sk = U[0:16]
        nonce = U[16:32]

        # ------------------------------------------------------------------ --

        # decrypt and verify challenge

        nonce_as_int = int_from_bytes(nonce, byteorder='big')
        ctr = Counter.new(128, initial_value=nonce_as_int)
        cipher = AES.new(sk, AES.MODE_CTR, counter=ctr)
        plaintext = cipher.decrypt(ciphertext)

        # ------------------------------------------------------------------ --

        # parse/check plaintext header

        # 1 - for content type
        # 8 - for transaction id
        # 8 - for time stamp
        offset = 1 + 8 + 8

        pt_header = plaintext[0:offset]
        (content_type,
         transaction_id,
         _time_stamp) = struct.unpack('<bQQ', pt_header)

        transaction_id = u64_to_transaction_id(transaction_id)

        # ------------------------------------------------------------------ --

        # prepare the parsed challenge data

        challenge = {}
        challenge['content_type'] = content_type

        # ------------------------------------------------------------------ --

        # retrieve plaintext data depending on content_type

        if content_type == CONTENT_TYPE_PAIRING:

            serial, callback_url, __ = plaintext[offset:].split('\x00')
            challenge['serial'] = serial

        elif content_type == CONTENT_TYPE_SIGNREQ:

            message, callback_url, __ = plaintext[offset:].split('\x00')
            challenge['message'] = message

        elif content_type == CONTENT_TYPE_LOGIN:

            login, host, callback_url, __ = plaintext[offset:].split('\x00')
            challenge['login'] = login
            challenge['host'] = host

        # ------------------------------------------------------------------ --

        # prepare the parsed challenge data

        challenge['callback_url'] = callback_url
        challenge['transaction_id'] = transaction_id
        challenge['user_token_id'] = user_token_id

        # calculate signature

        sig_base = (
            struct.pack('<b', CHALLENGE_URL_VERSION) +
            b'%s\0' % action +
            server_signature + plaintext)

        sig = crypto_sign_detached(sig_base, self.secret_key)
        encoded_sig = encode_base64_urlsafe(sig)

        return challenge, encoded_sig
Ejemplo n.º 44
0
 def test_iv_with_matching_length(self):
     self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_CTR,
                       counter=Counter.new(120))
     self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_CTR,
                       counter=Counter.new(136))
Ejemplo n.º 45
0
 def runTest(self):
     for pt, ct, key, prefix in self.bindata:
         counter = Counter.new(32, prefix=prefix)
         cipher = AES.new(key, AES.MODE_CTR, counter=counter)
         result = cipher.encrypt(pt)
         self.assertEqual(hexlify(ct), hexlify(result))
 def test_BE(self):
     """Big endian"""
     c = Counter.new(128)
     c = Counter.new(128, little_endian=False)
 def test_LE(self):
     """Little endian"""
     c = Counter.new(128, little_endian=True)
Ejemplo n.º 48
0
    def create_challenge_url(self,
                             transaction_id,
                             content_type,
                             callback_url='',
                             message=None,
                             login=None,
                             host=None):

        """
        creates a challenge url (looking like lseqr://push/<base64string>),
        returns the url and the unencrypted challenge data

        :param transaction_id: The transaction id generated by LinOTP

        :param content_type: One of the types CONTENT_TYPE_SIGNREQ,
            CONTENT_TYPE_PAIRING, CONTENT_TYPE_LOGIN

        :param callback_url: callback url (optional), default is
            empty string

        :param message: the transaction message, that should be signed
            by the client. Only for content type CONTENT_TYPE_SIGNREQ

        :param login: the login name of the user. Only for content type
            CONTENT_TYPE_LOGIN

        :param host: hostname of the user. Only for content type
            CONTENT_TYPE_LOGIN

        :returns: tuple (challenge_url, sig_base), with challenge_url being
            the push url and sig_base the message, that is used for
            the client signature
        """

        serial = self.getSerial()

        # ------------------------------------------------------------------- --

        # sanity/format checks

        if content_type not in [CONTENT_TYPE_SIGNREQ,
                                CONTENT_TYPE_PAIRING, CONTENT_TYPE_LOGIN]:
            raise InvalidFunctionParameter('content_type', 'content_type must '
                                           'be CONTENT_TYPE_SIGNREQ, '
                                           'CONTENT_TYPE_PAIRING or '
                                           'CONTENT_TYPE_LOGIN.')

        # ------------------------------------------------------------------- --

        #  after the lseqr://push/ prefix the following data is encoded
        #  in urlsafe base64:

        #            ---------------------------------------------------
        #  fields   | version | user token id |  R  | ciphertext | sign |
        #            ---------------------------------------------------
        #           |          header         |          body           |
        #            ---------------------------------------------------
        #  size     |    1    |       4       |  32 |      ?     |  64  |
        #            ---------------------------------------------------
        #

        # create header

        user_token_id = self.getFromTokenInfo('user_token_id')
        data_header = struct.pack('<bI', CHALLENGE_URL_VERSION, user_token_id)

        # ------------------------------------------------------------------- --

        # create body

        r = urandom(32)
        R = calc_dh_base(r)

        b64_user_dsa_public_key = self.getFromTokenInfo('user_dsa_public_key')
        user_dsa_public_key = b64decode(b64_user_dsa_public_key)
        user_dh_public_key = dsa_to_dh_public(user_dsa_public_key)

        ss = calc_dh(r, user_dh_public_key)
        U = SHA256.new(ss).digest()
        zerome(ss)

        sk = U[0:16]
        nonce = U[16:32]
        zerome(U)

        # ------------------------------------------------------------------- --

        # create plaintext section

        # ------------------------------------------------------------------- --

        # generate plaintext header

        #            ------------------------------------------------
        #  fields   | content_type  | transaction_id | timestamp | ..
        #            ------------------------------------------------
        #  size     |       1       |        8       |     8     |  ?
        #            -------------------------------------------------

        transaction_id = transaction_id_to_u64(transaction_id)
        plaintext = struct.pack('<bQQ', content_type, transaction_id,
                                int(time.time()))

        # ------------------------------------------------------------------- --

        utf8_callback_url = callback_url.encode('utf8')

        # enforce max url length as specified in protocol

        if len(utf8_callback_url) > 511:
            raise InvalidFunctionParameter('callback_url', 'max string '
                                           'length (encoded as utf8) is '
                                           '511')

        # ------------------------------------------------------------------- --

        # create data package depending on content type

        # ------------------------------------------------------------------- --

        if content_type == CONTENT_TYPE_PAIRING:

            #            -----------------------------------------
            #  fields   | header | serial | NUL | callback | NUL |
            #            -----------------------------------------
            #  size     |   9    |    ?   |  1  |     ?    |  1  |
            #            -----------------------------------------

            utf8_serial = serial.encode('utf8')

            if len(utf8_serial) > 63:
                raise ValueError('serial (encoded as utf8) can only be 63 '
                                 'characters long')

            plaintext += utf8_serial + b'\00' + utf8_callback_url + b'\00'

        # ------------------------------------------------------------------- --

        if content_type == CONTENT_TYPE_SIGNREQ:

            if message is None:
                raise InvalidFunctionParameter('message', 'message must be '
                                               'supplied for content type '
                                               'SIGNREQ')

            #            ------------------------------------------
            #  fields   | header | message | NUL | callback | NUL |
            #            ------------------------------------------
            #  size     |   9    |    ?    |  1  |     ?    |  1  |
            #            ------------------------------------------

            utf8_message = message.encode('utf8')

            # enforce max sizes specified by protocol

            if len(utf8_message) > 511:
                raise InvalidFunctionParameter('message', 'max string '
                                               'length (encoded as utf8) is '
                                               '511')

            plaintext += utf8_message + b'\00' + utf8_callback_url + b'\00'

        # ------------------------------------------------------------------- --

        if content_type == CONTENT_TYPE_LOGIN:

            if login is None:
                raise InvalidFunctionParameter('login', 'login must be '
                                               'supplied for content type '
                                               'LOGIN')
            if host is None:
                raise InvalidFunctionParameter('host', 'host must be '
                                               'supplied for content type '
                                               'LOGIN')

            #            -----------------------------------------------------
            #  fields   | header | login | NUL | host | NUL | callback | NUL |
            #            -----------------------------------------------------
            #  size     |   9    |   ?   |  1  |   ?  |  1  |     ?    |  1  |
            #            -----------------------------------------------------

            utf8_login = login.encode('utf8')
            utf8_host = host.encode('utf8')

            # enforce max sizes specified by protocol

            if len(utf8_login) > 127:
                raise InvalidFunctionParameter('login', 'max string '
                                               'length (encoded as utf8) is '
                                               '127')
            if len(utf8_host) > 255:
                raise InvalidFunctionParameter('host', 'max string '
                                               'length (encoded as utf8) is '
                                               '255')

            plaintext += utf8_login + b'\00'
            plaintext += utf8_host + b'\00'
            plaintext += utf8_callback_url + b'\00'

        # ------------------------------------------------------------------- --

        # encrypt inner layer

        nonce_as_int = int_from_bytes(nonce, byteorder='big')
        ctr = Counter.new(128, initial_value=nonce_as_int)
        cipher = AES.new(sk, AES.MODE_CTR, counter=ctr)
        ciphertext = cipher.encrypt(plaintext)
        unsigned_raw_data = data_header + R + ciphertext

        # ------------------------------------------------------------------- --

        # create signature

        partition = self.getFromTokenInfo('partition')
        secret_key = get_secret_key(partition)
        signature = crypto_sign_detached(unsigned_raw_data, secret_key)
        raw_data = unsigned_raw_data + signature

        protocol_id = config.get('mobile_app_protocol_id', 'lseqr')
        url = protocol_id + '://push/' + encode_base64_urlsafe(raw_data)

        return url, (signature + plaintext)
 def test_suffix(self):
     c = Counter.new(128, suffix=b("xx"))
 def test_nbits(self):
     c = Counter.new(nbits=128)
     self.assertRaises(ValueError, Counter.new, 129)
 def test_prefix(self):
     c = Counter.new(128, prefix=b("xx"))