Notice
Recent Posts
Recent Comments
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

topcue

Python AES CTR Set IV 본문

Python

Python AES CTR Set IV

topcue 2021. 1. 14. 09:41

AES CTR Set IV(counter value)

회사 과제를 하다가 AES-128 CTR 모드를 복호화 할 일이 있었다.

다음은 SwiftObjective-C로 작성된 iOS Signal의 encryptDeviceName() 함수다.

  • encryptDeviceName()
// cipher_key = HmacSHA256(key=HmacSHA256(key=master_secret, “cipher”), input=synthetic_iv)
let cipherKey = try computeCipherKey(masterSecret: masterSecret, syntheticIV: syntheticIV)

// cipher_text = AES-CTR(key=cipher_key, input=plaintext, counter=0)
//
// An all-zeros IV corresponds to an AES CTR counter of zero.
let ciphertextIV = Data(count: Int(kAES256CTR_IVLength))
guard let ciphertextKey = OWSAES256Key(data: cipherKey) else {
    owsFailDebug("Invalid cipher key.")
    throw DeviceNameError.assertionFailure
}
guard let ciphertext: AES256CTREncryptionResult = Cryptography.encryptAESCTR(
	plaintextData: plaintextData,
	initializationVector: ciphertextIV,
	key: ciphertextKey) else {
    owsFailDebug("Could not encrypt cipher text.")
    throw DeviceNameError.assertionFailure
}

IV(counter)를 랜덤하게 생성해서 AES CTR 모드를 이용해 암복호화하는 예제는 인터넷에 많았다.

그런데 IV를 특정한 값으로 지정하는 예제가 없었다.

만약 int형 counter를 인자로 전달하려 하면 에러가 발생한다.

ex) counter=1

AES256CTR = AES.new(cipher_key, AES.MODE_CTR, counter=1)
  • error
File "C:\Users\pc003\AppData\Local\Programs\Python\Python39\lib\site-packages\Cryptodome\Cipher\AES.py", line 232, in new
    return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
  File "C:\Users\pc003\AppData\Local\Programs\Python\Python39\lib\site-packages\Cryptodome\Cipher\__init__.py", line 79, in _create_cipher
    return modes[mode](factory, **kwargs)
  File "C:\Users\pc003\AppData\Local\Programs\Python\Python39\lib\site-packages\Cryptodome\Cipher\_mode_ctr.py", line 366, in _create_ctr_cipher
    _counter = dict(counter)
TypeError: 'int' object is not iterable

int가 아닌 object로 할당해야한다.


Crypto.Util.Counter

인자를 Crypto.Util.Counter로 전달해주면 된다.

아래는 AES-128 CTR에서 counter를 특정 정수로 지정한 테스트 코드다. specific_IV = 0

  • test code
#!/usr/bin/env python3
try:
	from pip import get_installed_distributions as pip_list
except:
	from pip._internal.utils.misc import get_installed_distributions as pip_list

packages=[]
[packages.append(pkg.key) for pkg in pip_list()]

if 'pycryptodome' in packages:
	from Crypto.Cipher import AES
	from Crypto.Util import Counter
elif 'pycryptodomex' in packages:
	from Cryptodome.Cipher import AES
	from Cryptodome.Util import Counter
else:
	print("install pycryptodome or pycryptodomex with:")
	print("`pip install pycryptodome` or `pip install pycryptodomex`")
	exit()


def AES_CTR_Test():
	# Set cipher key and iv
	cipher_key = b'00112233445566778899aabbccddeeff'
	specific_IV = 0 
	counter_value = Counter.new(128, initial_value=specific_IV)
	plaintext = b'THIS_IS_A_PLAIN_TEXT_LONGER_THAN_16BYTES'
	print("[plaintext]\n", plaintext)

	# Encrypt
	# ciphertext = AES-128-CTR-Encrypt(key=cipher_key, input=plaintext, counter=0)
	AES256CTR = AES.new(cipher_key, AES.MODE_CTR, counter=counter_value)
	ciphertext = AES256CTR.encrypt(plaintext)
	assert(len(ciphertext) == len(plaintext))
	print("[ciphertext]\n", ciphertext.hex())

	# Decrypt
	# plaintext = AES-128-CTR-Encrypt(key=cipher_key, input=ciphertext, counter=0)
	AES256CTR = AES.new(cipher_key, AES.MODE_CTR, counter=counter_value)
	recovered = AES256CTR.decrypt(ciphertext)
	assert(len(ciphertext) == len(plaintext))
	print("[recovered]\n", recovered)


def main():
	AES_CTR_Test()


if __name__ == '__main__':
	main()


# EOF
  • output
[plaintext]
 b'THIS_IS_A_PLAIN_TEXT_LONGER_THAN_16BYTES'
[ciphertext]
 e3e3805032ec378a18216992cfbfbe33d728bb6aac2c4e0c3730cbd8dd3cf68722feb5a518f4dcdf
[recovered]
 b'THIS_IS_A_PLAIN_TEXT_LONGER_THAN_16BYTES'

Swift와 위 코드로 크로스 체크했다.


참고

Signal-iOS/SignalServiceKit/src/Util/DeviceNames.swift:
https://github.com/signalapp/Signal-iOS/blob/master/SignalServiceKit/src/Util/DeviceNames.swift#L47


'Python' 카테고리의 다른 글

Python Yacht-Dice  (0) 2021.01.15
Python Curve25519 generate shared secret  (0) 2021.01.15
Python PyCryptodome - Crypto Packages  (0) 2021.01.14
파이썬 가상 실행 환경  (0) 2019.12.06
Comments