예제 #1
0
 def decrypt(self, enc):
     enc = base64.b64decode(enc)
     cipher = pyaes.blockfeeder.Decrypter(
         pyaes.AESModeOfOperationECB(self.key))
     plain_text = cipher.feed(enc)
     plain_text += cipher.feed()
     return plain_text
예제 #2
0
 def encrypt(self, raw):
     _ = self._pad(raw)
     cipher = pyaes.blockfeeder.Encrypter(
         pyaes.AESModeOfOperationECB(self.key.encode()))
     crypted_text = cipher.feed(raw)
     crypted_text += cipher.feed()
     return crypted_text
예제 #3
0
def bip38_encrypt(private_hex, address, password, flagbyte=b'\xe0'):
    """
    BIP0038 non-ec-multiply encryption. Returns BIP0038 encrypted private key
    Based on code from https://github.com/nomorecoin/python-bip38-testing

    :param private_hex: Private key in hex format
    :type private_hex: str
    :param address: Address string
    :type address: str
    :param password: Required password for encryption
    :type password: str
    :param flagbyte: Flagbyte prefix for WIF
    :type flagbyte: bytes

    :return str: BIP38 password encrypted private key
    """
    if isinstance(address, str):
        address = address.encode('utf-8')
    if isinstance(password, str):
        password = password.encode('utf-8')
    addresshash = double_sha256(address)[0:4]
    key = scrypt.hash(password, addresshash, 16384, 8, 8, 64)
    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]
    aes = pyaes.AESModeOfOperationECB(derivedhalf2)
    encryptedhalf1 = \
        aes.encrypt((int(private_hex[0:32], 16) ^ int.from_bytes(derivedhalf1[0:16], 'big')).to_bytes(16, 'big'))
    encryptedhalf2 = \
        aes.encrypt((int(private_hex[32:64], 16) ^ int.from_bytes(derivedhalf1[16:32], 'big')).to_bytes(16, 'big'))
    encrypted_privkey = b'\x01\x42' + flagbyte + addresshash + encryptedhalf1 + encryptedhalf2
    encrypted_privkey += double_sha256(encrypted_privkey)[:4]
    return change_base(encrypted_privkey, 256, 58)
예제 #4
0
    def bip38_encrypt(self, passphrase):
        """
        BIP0038 non-ec-multiply encryption. Returns BIP0038 encrypted privkey.
        Based on code from https://github.com/nomorecoin/python-bip38-testing

        :param passphrase: Required passphrase for encryption
        :type passphrase: str
        
        :return str: BIP38 passphrase encrypted private key
        """
        if self.compressed:
            flagbyte = b'\xe0'
            addr = self.address()
        else:
            flagbyte = b'\xc0'
            addr = self.address_uncompressed()

        privkey = self.private_hex
        if isinstance(addr, str) and sys.version_info > (3,):
            addr = addr.encode('utf-8')
        addresshash = hashlib.sha256(hashlib.sha256(addr).digest()).digest()[0:4]
        key = scrypt.hash(passphrase, addresshash, 16384, 8, 8)
        derivedhalf1 = key[0:32]
        derivedhalf2 = key[32:64]
        aes = pyaes.AESModeOfOperationECB(derivedhalf2)
        encryptedhalf1 = aes.encrypt(binascii.unhexlify('%0.32x' % (int(privkey[0:32], 16) ^
                                                                    int(binascii.hexlify(derivedhalf1[0:16]), 16))))
        encryptedhalf2 = aes.encrypt(binascii.unhexlify('%0.32x' % (int(privkey[32:64], 16) ^
                                                                    int(binascii.hexlify(derivedhalf1[16:32]), 16))))
        encrypted_privkey = b'\x01\x42' + flagbyte + addresshash + encryptedhalf1 + encryptedhalf2
        encrypted_privkey += hashlib.sha256(hashlib.sha256(encrypted_privkey).digest()).digest()[:4]
        return change_base(encrypted_privkey, 256, 58)
예제 #5
0
def bip38_encrypt(private_hex, address, passphrase, flagbyte=b'\xe0'):
    """
    BIP0038 non-ec-multiply encryption. Returns BIP0038 encrypted private key
    Based on code from https://github.com/nomorecoin/python-bip38-testing

    :param private_hex: Private key in hex format
    :type private_hex: str
    :param address: Address string
    :type address: str
    :param passphrase: Required passphrase for encryption
    :type passphrase: str
    :param flagbyte: Flagbyte prefix for WIF
    :type flagbyte: bytes

    :return str: BIP38 passphrase encrypted private key
    """
    if isinstance(address, str) and sys.version_info > (3,):
        address = address.encode('utf-8')
    if isinstance(passphrase, str) and sys.version_info > (3,):
        passphrase = passphrase.encode('utf-8')
    addresshash = double_sha256(address)[0:4]
    key = scrypt.hash(passphrase, addresshash, 16384, 8, 8, 64)
    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]
    aes = pyaes.AESModeOfOperationECB(derivedhalf2)
    encryptedhalf1 = aes.encrypt(binascii.unhexlify('%0.32x' % (int(private_hex[0:32], 16) ^
                                                                int(binascii.hexlify(derivedhalf1[0:16]), 16))))
    encryptedhalf2 = aes.encrypt(binascii.unhexlify('%0.32x' % (int(private_hex[32:64], 16) ^
                                                                int(binascii.hexlify(derivedhalf1[16:32]), 16))))
    encrypted_privkey = b'\x01\x42' + flagbyte + addresshash + encryptedhalf1 + encryptedhalf2
    encrypted_privkey += double_sha256(encrypted_privkey)[:4]
    return change_base(encrypted_privkey, 256, 58)
예제 #6
0
    def _decryptNoEC(self, passphrase : str) -> tuple: # returns the (WIF private key, Address)  on success, raises Error on failure.
        assert isinstance(passphrase, str), "Passphrase must be a string!"
        scryptBuf = Bip38Key._scrypt(password = passphrase, salt = self.salt, N=16384, r=8, p=8, dkLen=64)
        derivedHalf1 = scryptBuf[0:32]
        derivedHalf2 = scryptBuf[32:64]
        encryptedHalf1 = self.dec[7:23]
        encryptedHalf2 = self.dec[23:39]

        h = pyaes.AESModeOfOperationECB(derivedHalf2)
        k1 = h.decrypt(encryptedHalf1)
        k2 = h.decrypt(encryptedHalf2)

        keyBytes = bytearray(32)
        for i in range(16):
            keyBytes[i] = k1[i] ^ derivedHalf1[i]
            keyBytes[i+16] = k2[i] ^ derivedHalf1[i+16]
        keyBytes = bytes(keyBytes)

        eckey = regenerate_key(keyBytes)

        pubKey = eckey.GetPubKey(self.compressed)

        from .address import Address

        addr = Address.from_pubkey(pubKey)
        addrHashed = Hash(addr.to_storage_string(net=self.net))[0:4]

        assert len(addrHashed) == len(self.salt)

        for i in range(len(addrHashed)):
            if addrHashed[i] != self.salt[i]:
                raise Bip38Key.PasswordError('Supplied password failed to decrypt bip38 key.')

        return serialize_privkey(keyBytes, self.compressed, 'p2pkh', net=self.net), addr
예제 #7
0
 def decrypt(self,cipherText):
     cryptor = pyaes.AESModeOfOperationECB(self.key)
     plainText = cryptor.decrypt(a2b_hex(cipherText))
     # 将秘钥转换为二进制流
     # 返回值为二进制流,因为有很多不可打印字符
     # plainText = cryptor.decrypt(a2b_base64(cipherText))
     return plainText
예제 #8
0
파일: espsecure.py 프로젝트: NoMaY-tmp/ex3
def digest_secure_bootloader(args):
    """ Calculate the digest of a bootloader image, in the same way the hardware
    secure boot engine would do so. Can be used with a pre-loaded key to update a
    secure bootloader. """
    if args.iv is not None:
        print("WARNING: --iv argument is for TESTING PURPOSES ONLY")
        iv = args.iv.read(128)
    else:
        iv = os.urandom(128)
    plaintext_image = args.image.read()
    args.image.seek(0)

    # secure boot engine reads in 128 byte blocks (ie SHA512 block
    # size), but also doesn't look for any appended SHA-256 digest
    fw_image = esptool.ESP32FirmwareImage(args.image)
    if fw_image.append_digest:
        if len(plaintext_image) % 128 <= 32:
            # ROM bootloader will read to the end of the 128 byte block, but not
            # to the end of the SHA-256 digest at the end
            new_len = len(plaintext_image) - (len(plaintext_image) % 128)
            plaintext_image = plaintext_image[:new_len]

    # if image isn't 128 byte multiple then pad with 0xFF (ie unwritten flash)
    # as this is what the secure boot engine will see
    if len(plaintext_image) % 128 != 0:
        plaintext_image += "\xFF" * (128 - (len(plaintext_image) % 128))

    plaintext = iv + plaintext_image

    # Secure Boot digest algorithm in hardware uses AES256 ECB to
    # produce a ciphertext, then feeds output through SHA-512 to
    # produce the digest. Each block in/out of ECB is reordered
    # (due to hardware quirks not for security.)

    key = _load_hardware_key(args.keyfile)
    aes = pyaes.AESModeOfOperationECB(key)
    digest = hashlib.sha512()

    for block in get_chunks(plaintext, 16):
        block = block[::-1]  # reverse each input block

        cipher_block = aes.encrypt(block)
        # reverse and then byte swap each word in the output block
        cipher_block = cipher_block[::-1]
        for block in get_chunks(cipher_block, 4):
            # Python hashlib can build each SHA block internally
            digest.update(block[::-1])

    if args.output is None:
        args.output = os.path.splitext(
            args.image.name)[0] + "-digest-0x0000.bin"
    with open(args.output, "wb") as f:
        f.write(iv)
        digest = digest.digest()
        for word in get_chunks(digest, 4):
            f.write(word[::-1])  # swap word order in the result
        f.write(b'\xFF' * (0x1000 - f.tell()))  # pad to 0x1000
        f.write(plaintext_image)
    print("digest+image written to %s" % args.output)
    def encryptECB(uint8Array, key):
        aes = pyaes.AESModeOfOperationECB(key)

        stringPayload = "".join(chr(b) for b in uint8Array)

        encrypted = aes.encrypt(stringPayload)

        return encrypted
예제 #10
0
 def __init__(self, seed=None):
     if seed is None:
         self.key = os.urandom(32)
     else:
         assert len(seed) in [16, 24, 32]
         self.key = seed
     self.aes = pyaes.AESModeOfOperationECB(self.key)
     self.state = [0, 1, 2, 3]
     self.state_len = len(self.state)
예제 #11
0
def get_seed_from_ewifv1(ewif, password):
    regex = re.compile('^[1-9A-HJ-NP-Za-km-z]*$')
    if not re.search(regex, ewif):
        print("Error: the format of EWIF is invalid")
        sys.exit(1)

    wif_bytes = b58_decode(ewif)
    if len(wif_bytes) != 39:
        print("Error: the size of EWIF is invalid")
        sys.exit(1)

    wif_no_checksum = wif_bytes[0:-2]
    checksum_from_ewif = wif_bytes[-2:]
    fi = wif_bytes[0:1]
    salt = wif_bytes[1:5]
    encryptedhalf1 = wif_bytes[5:21]
    encryptedhalf2 = wif_bytes[21:37]

    if fi != b'\x02':
        print("Error: It's not a EWIF format")
        sys.exit(1)

    # Checksum Control
    checksum = nacl.hash.sha256(
        nacl.hash.sha256(wif_no_checksum, nacl.encoding.RawEncoder),
        nacl.encoding.RawEncoder)[0:2]
    if checksum_from_ewif != checksum:
        print("Error: bad checksum of EWIF address")
        sys.exit(1)

    # SCRYPT
    password = password.encode("utf-8")
    scrypt_seed = scrypt.hash(password, salt, 16384, 8, 8, 64)
    derivedhalf1 = scrypt_seed[0:32]
    derivedhalf2 = scrypt_seed[32:64]

    # AES
    aes = pyaes.AESModeOfOperationECB(derivedhalf2)
    decryptedhalf1 = aes.decrypt(encryptedhalf1)
    decryptedhalf2 = aes.decrypt(encryptedhalf2)

    # XOR
    seed1 = xor_bytes(decryptedhalf1, derivedhalf1[0:16])
    seed2 = xor_bytes(decryptedhalf2, derivedhalf1[16:32])
    seed = seed1 + seed2
    seedhex = nacl.encoding.HexEncoder.encode(seed).decode("utf-8")

    # Password Control
    salt_from_seed = nacl.hash.sha256(
        nacl.hash.sha256(b58_decode(get_publickey_from_seed(seedhex)),
                         nacl.encoding.RawEncoder),
        nacl.encoding.RawEncoder)[0:4]
    if salt_from_seed != salt:
        print("Error: bad Password of EWIF address")
        sys.exit(1)

    return seedhex
예제 #12
0
def encrypt_message(plaintext, id):
    key = array_clients[int(id)].aes_key.encode()

    encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationECB(key))
    ciphertext = encrypter.feed(plaintext)
    ciphertext += encrypter.feed()

    ciphertextbase64 = base64.b64encode(ciphertext)
    return ciphertextbase64.decode()
def DekriptimiMeECB(ciphertext,celesi): #PADDED
    decrypted = []
    decrypted_1 = []
    aes = pyaes.AESModeOfOperationECB(celesi)
    ciphertext_list = re.findall('.{1,16}', ciphertext.decode('utf-8'))
    for i in range(len(ciphertext_list)):
        decrypted.append(aes.decrypt(ciphertext_list[i]))
        decrypted_1.append(decrypted[i].decode("utf-8"))
    decrypted_padded_str = ''.join(str(e) for e in decrypted_1)
    return decrypted_padded_str
예제 #14
0
    def get_stream(self, quality):
        quality_to_number = {
            'MP3_128': '1',
            'MP3_320': '3',
            'FLAC': '9',
            '360_RA3': '15',
            '360_RA2': '14',
            '360_RA1': '13',
        }
        quality = quality_to_number[quality]

        # get track url
        # step 1: put a bunch of info together and hash it
        step1 = b'\xa4'.join(map(lambda s: s.encode(), [
            self.md5_origin,
            quality,
            str(self.song_id),
            self.media_version
        ]
        ))

        hash = hashlib.new('md5')
        hash.update(step1)
        step1_hash = hash.hexdigest()

        #  - step 2: hash + info + add padding
        step2 = str.encode(step1_hash) + b'\xa4' + step1 + b'\xa4'
        while len(step2) % 16 > 0:
            step2 += b'.'

        #  - step 3: AES encryption to get url
        # it will encrypt in parts of 16
        step3 = b''
        aes = pyaes.AESModeOfOperationECB(b'jo6aey6haid2Teih')
        for index in range(int(len(step2) / 16)):
            block = step2[(index * 16):(index * 16) + 16]
            step3 += binascii.hexlify(aes.encrypt(block))

        #  - step 4: make url
        url = 'http://e-cdn-proxy-{}.deezer.com/mobile/1/{}'.format(
            self.md5_origin[0],  # first char of md5origin is cdn to use
            step3.decode('utf-8')
        )

        try:
            response = urlopen(url)
        except urllib.error.HTTPError as e:
            return False
        except ConnectionResetError as e:
            print(e)
            raise NotImplementedError('Error getting deezer track url')

        output_stream = bytearray()
        return DeezerTrackStream(url)
예제 #15
0
 def encode_line(plaintext, real_key, buf_len):
     aes = pyaes.AESModeOfOperationECB(real_key)
     text_len = len(plaintext)
     pad_len = buf_len - text_len
     pad_chr = bytes(chr(pad_len), "utf8")
     plaintext = plaintext.encode() + pad_chr * pad_len
     encrypted_text = b''.join([
         aes.encrypt(plaintext[i:i + 16])
         for i in range(0, len(plaintext), 16)
     ])
     return encrypted_text
예제 #16
0
def aes_ecb_dec(blob: bytes, key: bytes) -> bytes:
    """
    Decodes the blob in 16 bytes chunks.
    Returns the concatination of all 16 byte results.
    """
    aes = pyaes.AESModeOfOperationECB(key)
    comb = b''

    for b in divide(blob, 16):
        comb += aes.decrypt(b)

    return comb
예제 #17
0
    def __decrypt(self, ciphertext):
        try:
            ciphertext = base64.b64decode(ciphertext)

            decrypter = pyaes.Decrypter(pyaes.AESModeOfOperationECB(self.key))
            plaintext = decrypter.feed(ciphertext)
            plaintext += decrypter.feed()

            return plaintext

        except Exception:
            return
예제 #18
0
    def from_ewif_hex(cls: Type[SigningKeyType], ewif_hex: str, password: str) -> SigningKeyType:
        """
        Return SigningKey instance from Duniter EWIF in hexadecimal format

        :param ewif_hex: EWIF string in hexadecimal format
        :param password: Password of the encrypted seed
        """
        ewif_bytes = Base58Encoder.decode(ewif_hex)
        if len(ewif_bytes) != 39:
            raise Exception("Error: the size of EWIF is invalid")

        # extract data
        fi = ewif_bytes[0:1]
        checksum_from_ewif = ewif_bytes[-2:]
        ewif_no_checksum = ewif_bytes[0:-2]
        salt = ewif_bytes[1:5]
        encryptedhalf1 = ewif_bytes[5:21]
        encryptedhalf2 = ewif_bytes[21:37]

        # check format flag
        if fi != b"\x02":
            raise Exception("Error: bad format version, not EWIF")

        # checksum control
        checksum = libnacl.crypto_hash_sha256(libnacl.crypto_hash_sha256(ewif_no_checksum))[0:2]
        if checksum_from_ewif != checksum:
            raise Exception("Error: bad checksum of the EWIF")

        # SCRYPT
        password_bytes = password.encode("utf-8")
        scrypt_seed = scrypt(password_bytes, salt, 16384, 8, 8, 64)
        derivedhalf1 = scrypt_seed[0:32]
        derivedhalf2 = scrypt_seed[32:64]

        # AES
        aes = pyaes.AESModeOfOperationECB(derivedhalf2)
        decryptedhalf1 = aes.decrypt(encryptedhalf1)
        decryptedhalf2 = aes.decrypt(encryptedhalf2)

        # XOR
        seed1 = xor_bytes(decryptedhalf1, derivedhalf1[0:16])
        seed2 = xor_bytes(decryptedhalf2, derivedhalf1[16:32])
        seed = bytes(seed1 + seed2)

        # Password Control
        signer = SigningKey(seed)
        salt_from_seed = libnacl.crypto_hash_sha256(
            libnacl.crypto_hash_sha256(
                Base58Encoder.decode(signer.pubkey)))[0:4]
        if salt_from_seed != salt:
            raise Exception("Error: bad Password of EWIF address")

        return cls(seed)
예제 #19
0
def digest_secure_bootloader(args):
    """ Calculate the digest of a bootloader image, in the same way the hardware
    secure boot engine would do so. Can be used with a pre-loaded key to update a
    secure bootloader. """
    if args.iv is not None:
        print("WARNING: --iv argument is for TESTING PURPOSES ONLY")
        iv = args.iv.read(128)
    else:
        iv = os.urandom(128)
    plaintext_image = args.image.read()

    # secure boot engine reads in 128 byte blocks (ie SHA512 block
    # size) , so pad plaintext image with 0xFF (ie unwritten flash)
    if len(plaintext_image) % 128 != 0:
        plaintext_image += "\xFF" * (128 - (len(plaintext_image) % 128))

    plaintext = iv + plaintext_image

    # Secure Boot digest algorithm in hardware uses AES256 ECB to
    # produce a ciphertext, then feeds output through SHA-512 to
    # produce the digest. Each block in/out of ECB is reordered
    # (due to hardware quirks not for security.)

    key = args.keyfile.read()
    if len(key) != 32:
        raise esptool.FatalError(
            "Key file contains wrong length (%d bytes), 32 expected." %
            len(key))
    aes = pyaes.AESModeOfOperationECB(key)
    digest = hashlib.sha512()

    for block in get_chunks(plaintext, 16):
        block = block[::-1]  # reverse each input block

        cipher_block = aes.encrypt(block)
        # reverse and then byte swap each word in the output block
        cipher_block = cipher_block[::-1]
        for block in get_chunks(cipher_block, 4):
            # Python hashlib can build each SHA block internally
            digest.update(block[::-1])

    if args.output is None:
        args.output = os.path.splitext(
            args.image.name)[0] + "-digest-0x0000.bin"
    with open(args.output, "wb") as f:
        f.write(iv)
        digest = digest.digest()
        for word in get_chunks(digest, 4):
            f.write(word[::-1])  # swap word order in the result
        f.write(b'\xFF' * (0x1000 - f.tell()))  # pad to 0x1000
        f.write(plaintext_image)
    print("digest+image written to %s" % args.output)
예제 #20
0
 def encrypt(self, raw):
     if AES:
         raw = self._pad(raw)
         cipher = AES.new(self.key, mode=AES.MODE_ECB, IV='')
         crypted_text = cipher.encrypt(raw)
     else:
         cipher = pyaes.blockfeeder.Encrypter(
             pyaes.AESModeOfOperationECB(
                 self.key))  # no IV, auto pads to 16
         crypted_text = cipher.feed(raw)
         crypted_text += cipher.feed()  # flush final block
     #print('crypted_text %r' % crypted_text)
     return base64.b64encode(crypted_text)
예제 #21
0
    def decrypt(self, enc, use_base64=True):
        if use_base64:
            enc = base64.b64decode(enc)

        # if Crypto:
        #     cipher = AES.new(self.key, AES.MODE_ECB)
        #     raw = cipher.decrypt(enc)
        #     return self._unpad(raw).decode('utf-8')
        # else:
        cipher = pyaes.blockfeeder.Decrypter(pyaes.AESModeOfOperationECB(self.key))
        plain_text = cipher.feed(enc)
        plain_text += cipher.feed()
        return plain_text
예제 #22
0
 def decrypt(self, enc):
     enc = base64.b64decode(enc)
     if Crypto:
         cipher = AES.new(self.key, AES.MODE_ECB)
         raw = cipher.decrypt(enc)
         return self._unpad(raw).decode('utf-8')
     else:
         cipher = pyaes.blockfeeder.Decrypter(
             pyaes.AESModeOfOperationECB(
                 self.key))  # no IV, auto pads to 16
         plain_text = cipher.feed(enc)
         plain_text += cipher.feed()  # flush final block
         return plain_text
예제 #23
0
def decrypt_message(ciphertextb64, id):
    key = array_clients[int(id)].aes_key.encode()

    ciphertextb64 = base64.b64decode(ciphertextb64)

    decryptor = pyaes.Decrypter(pyaes.AESModeOfOperationECB(key))
    decryptedmessage = decryptor.feed(ciphertextb64)
    decryptedmessage = decryptor.feed(
        ciphertextb64[:int(len(ciphertextb64) / 2)])
    decryptedmessage += decryptor.feed(
        ciphertextb64[int(len(ciphertextb64) / 2):])

    return decryptedmessage.decode()
예제 #24
0
def _flash_encryption_operation(output_file, input_file, flash_address,
                                keyfile, flash_crypt_conf, do_decrypt):
    key = keyfile.read()
    if len(key) != 32:
        raise esptool.FatalError(
            "Key file contains wrong length (%d bytes), 32 expected." %
            len(key))

    if flash_address % 16 != 0:
        raise esptool.FatalError(
            "Starting flash address 0x%x must be a multiple of 16" %
            flash_address)

    if flash_crypt_conf == 0:
        print("WARNING: Setting FLASH_CRYPT_CONF to zero is not recommended")
    tweak_range = _flash_encryption_tweak_range(flash_crypt_conf)

    aes = None
    while True:
        block_offs = flash_address + input_file.tell()
        block = input_file.read(16)
        if len(block) == 0:
            break
        elif len(block) < 16:
            if do_decrypt:
                raise esptool.FatalError(
                    "Data length is not a multiple of 16 bytes")
            pad = 16 - len(block)
            block = block + os.urandom(pad)
            print(
                "WARNING: Padding with %d bytes of random data (encrypted data must be multiple of 16 bytes long)"
                % pad)

        if (block_offs % 32 == 0) or aes is None:
            # each bit of the flash encryption key is XORed with tweak bits derived from the offset of 32 byte block of flash
            block_key = _flash_encryption_tweak_key(key, block_offs,
                                                    tweak_range)
            aes = pyaes.AESModeOfOperationECB(block_key)

        block = block[::-1]  # reverse input block byte order

        # note AES is used inverted for flash encryption, so
        # "decrypting" flash uses AES encrypt algorithm and vice
        # versa. (This does not weaken AES.)
        if do_decrypt:
            block = aes.encrypt(block)
        else:
            block = aes.decrypt(block)

        block = block[::-1]  # reverse output block byte order
        output_file.write(block)
예제 #25
0
    def instantiate(self, entropy_in, per_string=b''):
        '''
            Method handling initialization of the DRBG (see Specification)

           Parameters
           ----------
           entropy_in : hex byterray (e.g. \xFF\xF1....etc (len = seedlen_bits /8))
                       full entropy seed for DRBG, it must be seedlen bits

           per_string : hex byterray (e.g. \xFF\xF1....etc (len must be less or equal seedlen))
                       additional input which will be xored with the input entropy for added security (optional)

           Returns
           -------


        '''

        if len(per_string) is not 0:

            temp = len(per_string)  # NB len is in bytes

            if temp < self.seedlen:

                per_string = per_string + b"\x00" * (self.seedlen - temp
                                                     )  # pad

            else:

                raise ValueError(
                    "Length of personalization string must be equal or less than seedlen"
                )

        else:

            per_string = b"\x00" * self.seedlen

        seed_material = int(entropy_in.hex(), 16) ^ int(per_string.hex(), 16)
        seed_material = seed_material.to_bytes(self.seedlen,
                                               byteorder='big',
                                               signed=False)

        self.key = b"\x00" * self.keylen
        self.V = b"\x00" * self.outlen

        self.aes = pyaes.AESModeOfOperationECB(self.key)

        self._update(seed_material)

        self.reseed_counter = 1
예제 #26
0
 def encrypt(self, raw):
     if Crypto:
         raw = self._pad(raw)
         cipher = AES.new(self.key, mode=AES.MODE_ECB)
         crypted_text = cipher.encrypt(raw)
     else:
         _ = self._pad(raw)
         cipher = pyaes.blockfeeder.Encrypter(
             pyaes.AESModeOfOperationECB(
                 self.key))  # no IV, auto pads to 16
         crypted_text = cipher.feed(raw)
         crypted_text += cipher.feed()  # flush final block
     crypted_text_b64 = base64.b64encode(crypted_text)
     return crypted_text_b64
예제 #27
0
    def change_key(self, master_key):
        """Given a new master key, prepare a new auth key"""
        self.__master_key = long_to_bytes(master_key, 32)
        self.__aes_ecb = pyaes.AESModeOfOperationECB(self.__master_key)
        self.__auth_key = bytes_to_long(self.__aes_ecb.encrypt(b"\x00" * 16))

        # precompute the table for multiplication in finite field
        table = []  # for 8-bit
        for i in range(16):
            row = []
            for j in range(256):
                row.append(self.gf_2_128_mul(self.__auth_key, j << (8 * i)))
            table.append(tuple(row))
        self.__pre_table = tuple(table)
예제 #28
0
    async def encrypt(self, data, b64=True) -> bytes:
        #data = self._pad(data)
        #cipher = AES.new(self._key, AES.MODE_ECB)
        #encrypted_data = cipher.encrypt(data)

        cipher = pyaes.blockfeeder.Encrypter(
            pyaes.AESModeOfOperationECB(self._key))
        encrypted_data = cipher.feed(data)
        encrypted_data += cipher.feed()

        if b64:
            return base64.b64encode(encrypted_data)
        else:
            return encrypted_data
예제 #29
0
    def _bip38_decrypt(encrypted_privkey, passphrase):
        """
        BIP0038 non-ec-multiply decryption. Returns WIF private key.
        Based on code from https://github.com/nomorecoin/python-bip38-testing
        This method is called by Key class init function when importing BIP0038 key.

        :param encrypted_privkey: Encrypted private key using WIF protected key format
        :type encrypted_privkey: str
        :param passphrase: Required passphrase for decryption
        :type passphrase: str
        
        :return str: Private Key WIF
        """
        # TODO: Also check first 2 bytes
        d = change_base(encrypted_privkey, 58, 256)[2:]
        flagbyte = d[0:1]
        d = d[1:]
        if flagbyte == b'\xc0':
            compressed = False
        elif flagbyte == b'\xe0':
            compressed = True
        else:
            raise Warning("Unrecognised password protected key format. Flagbyte incorrect.")
        addresshash = d[0:4]
        d = d[4:-4]
        key = scrypt.hash(passphrase, addresshash, 16384, 8, 8)
        derivedhalf1 = key[0:32]
        derivedhalf2 = key[32:64]
        encryptedhalf1 = d[0:16]
        encryptedhalf2 = d[16:32]
        aes = pyaes.AESModeOfOperationECB(derivedhalf2)
        decryptedhalf2 = aes.decrypt(encryptedhalf2)
        decryptedhalf1 = aes.decrypt(encryptedhalf1)
        priv = decryptedhalf1 + decryptedhalf2
        priv = binascii.unhexlify('%064x' % (int(binascii.hexlify(priv), 16) ^ int(binascii.hexlify(derivedhalf1), 16)))
        if compressed:
            # FIXME: This works but does probably not follow the BIP38 standards (was before: priv = b'\0' + priv)
            priv += b'\1'
            key_format = 'wif_compressed'
        else:
            key_format = 'wif'
        k = Key(priv, compressed=compressed)
        wif = k.wif()
        addr = k.address()
        if isinstance(addr, str) and sys.version_info > (3,):
            addr = addr.encode('utf-8')
        if hashlib.sha256(hashlib.sha256(addr).digest()).digest()[0:4] != addresshash:
            print('Addresshash verification failed! Password is likely incorrect.')
        return wif, key_format
예제 #30
0
 def encrypt(self, raw, use_base64 = True):
     if Crypto:
         raw = self._pad(raw)
         cipher = AES.new(self.key, mode=AES.MODE_ECB)
         crypted_text = cipher.encrypt(raw)
     else:
         _ = self._pad(raw)
         cipher = pyaes.blockfeeder.Encrypter(pyaes.AESModeOfOperationECB(self.key))  # no IV, auto pads to 16
         crypted_text = cipher.feed(raw)
         crypted_text += cipher.feed()  # flush final block
     #print('crypted_text (%d) %r' % (len(crypted_text), crypted_text))
     if use_base64:
         return base64.b64encode(crypted_text)
     else:
         return crypted_text