pycrypto AES-CTR 实现自定义计数器递增

0 投票
1 回答
551 浏览
提问于 2025-04-18 04:43

我需要实现AES-CTR解密,并且要用自定义的计数器来增加。为此,我需要做以下几件事:

  1. 从文件中读取加密的数据。(文件数据如下)
  2. 获取前8个字节作为随机数(nonce)。
  3. 接下来的两个字节用作随机数的计数器增量。

写的代码如下:

from Crypto.Cipher import AES
from Crypto.Util import Counter
import array
class Secret(object):
    def __init__(self, secret=None, count=None):
        self.secret = secret
        self.count = count
        self.reset()
    @staticmethod
    def counter(self):
        self.secret = int(''.join(self.secret),16) + int(''.join(self.count),16)
        self.secret = format(self.secret, 'x')
        self.secret = self.secret.decode("hex")
        self.secret = map(ord, self.secret)
        self.secret = [format(x, 'x') for x in self.secret]
        return self.current.tostring()
    def reset(self):
        self.current = array.array('B', [int(x,16) for x in self.secret])
        print(self.current)


def decrypt(key, data, nonce):
    cipher_ctr = AES.new(key, mode=AES.MODE_CTR, counter=nonce.counter)
    plaintext = cipher_ctr.decrypt(data)
    return ''.join(plaintext)

def main():
    cipher_file = open('data.txt', 'r')
    cipher_data = cipher_file.read(197)
    cipher_data = cipher_data.split(':')
    cipher_nonce = cipher_data[:8]
    cipher_counter = cipher_data[8:10]
    cipher_nonce = Secret(cipher_nonce,cipher_counter)
    cipher_data = cipher_data[10:]
    cipher_key = b'this is a key123'
    plain_text = decrypt(''.join(cipher_key), hex(int(''.join(cipher_data),16)), cipher_nonce)


if __name__ == '__main__':
    main()

但是在这个过程中遇到了错误,请帮帮我。

TypeError: counter() takes exactly 1 argument (0 given)

数据文件包含:

c2:57:0a:35:da:41:e7:75:24:03:97:b6:66:b3:15:27:f1:bb:56:ba:6e:2c:3a:35:d3:86:b5:95:62:a1:7d:03:b2:b6:3c:c4:d6:73:6d:77:20:f2:1b:7e:d8:3b:f2:0a:5e:be:36:19:57:be:1f:0a:f9:4c:9b:8a:c3:1a:89:4e:ff:d5:b2:e1:42:65:d5:1d:7f:e2:16:11:80:8b:f4:a5:bf:34:e4:f1:60:3c:04:36:3a:57:d1:4c:4f:98:6c:60:cb:d8:c8:b0:88:67:cb:89:0e:8c:8d:f2:ad:5b:ee:b8:cb:a5:20:b0:d9:ef:57:b9:2f:a6:cb:6e:9c:64:07:37:8b:82:c5:c1:3d:0b:a4:ef:2d:75:83:6d:c0:81:e0:18:3d:ed:72:a3:39:4e:e4:94:89:c6:ea:34:b7:5b:e5:fe:56:e4:7d:16:73:29:d5:c4:82:8f:f9:f5:0e:73:85:50:65:3e:a7:bf:8b:bc:77:05:04:f7:d3:12:d6:06:92:43:cd:6b:7b:5a:4c:55:68:80:ba:cb:a1:ec:2e:b8:e4:fe:00:f9:88:d8:14:10:e5:ee:f9:b3:a6:8c:38:bd:1d:b7:ac:27:09:ab:bf:35:c7:a6:61:05:df:68:f5:67:8b:e6:fe:71:09:96:19:fe:2d:3d:a6:5c:b2:1c:47:cc:b6:ed:13:3a:c0:41:f2:af:de:a2:77:e2:70:25:b1:d6:72:cc:a8:2c:cb:39:77:e4:19:09:62:46:34:82:7f:ab:c7:b6:36:3b:ef:1e:d1:69:88:09:96:75:c1:17:d3:01:6d:7b:ca:7d:9b:52:39:2b:24:63:fd:7b:9f:bd:4c:41:87:0e:95:85:ef:5f:d7:a2:8b:02:86:1e:dd:cd:1c:29:fe:c1:ab:f1:df:44:37:30:32:5d:ad:c1:43:10:bb:94:64:95:85:18:82:80:b8:56:63:cf:10:f5:f9:9e:bb:87:1e:41:46:bb:cb:ae:ce:36:35:45:2e:ad:09:dd:d7:6e:55:09:8f:20:28:fd:ed:16:46:37:41:f9:16:39:32:03:ad:5d:87:b0:ba:1b:fd:01:8b:b8:4d:81:ba:e4:e8:66:98:5f:e9:2d:39:1c:f3:cd:2c:d8:50:87:5b:d1:e1:24:95:f6:3f:94:e4:9d:77:12:1d:49:c2:01:6c:71:91:0c:bf:18:32:06:f0:39:23:c1:a5:fc:46:35:a5:b8:d7:82:99:74:53:63:ed:42:8e:ab:a6:fa:d9:59:a9:ef:54:41:26:4e:f8:55:0c:1b:2c:14:99:e5:03:44:70:eb:09:be:d9:ae:da:a9:bf:5a:6f:f5:d6:23:a3:6d:8a:7a:74:ea:62:8c:c4:67:ed:eb:1b:e0:eb:7a:1d:fd:ce:e7:73:bf:1e:e2:b5:7d:ee:3f:f1:bd:0d:15:51:9f:8c:44:79:a9:c6:ae:04:7b:24:17:4d:be:81:14:75:66:7f:2b:8b:f9:09:73:00:75:b3:2d:d7:27:72:93:3b:52:fe:c4:16:6c:0d:e9:83:56:11:7b:3a:36:e9:5e:c2:9c:c7:59:40

1 个回答

1

这个方法 Secret.counter 本来应该是静态的,但它却还要接收 self 作为参数,并且试图访问实例成员(比如 self.secret)。这样做是不行的。

如果你把 Secret.counter 改名为 __call__,并把它变成一个普通的方法(而不是静态方法),那就简单多了。这样,每个 Secret 的实例就可以像函数一样被调用,可以用作 AES 的计数器。

撰写回答