据@gertvdijk,AES_CTR是不流密码 并不 需要填充。所以我删除了相关代码。
这是我所知道的。
您必须
AES.new(...)
在加密和解密中使用相同的密钥(中的第一个参数),并将密钥保密。加密/解密方法是 有状态的 ,这意味着
crypto.en(de)crypt("abcd")==crypto.en(de)crypt("abcd")是 不 总是如此。在您的点击率中,计数器回调始终返回相同的内容,因此在加密时它变为无状态(我不是100%确信这是原因),但我们仍然发现它在解密中有些状态。结论是,我们应该始终使用一个新的对象来执行它们。counter callback
加密和解密中的功能应具有相同的行为。在您的情况下,是使它们都返回相同的秘密。但是我不认为这secret
是“秘密”。您可以使用生成的随机数"secret"
,并在不进行任何加密的情况下将其传递给通信的对等方,以便另一端可以直接使用它, 前提secret
是 不可预测的 。
因此,我将这样编写密码,希望它会有所帮助。
import osimport hashlibimport Crypto.Cipher.AES as AESclass Cipher: @staticmethod def md5sum( raw ): m = hashlib.md5() m.update(raw) return m.hexdigest() BS = AES.block_size @staticmethod def pad( s ): """note that the padding is no necessary""" """return s + (Cipher.BS - len(s) % Cipher.BS) * chr(Cipher.BS - len(s) % Cipher.BS)""" return s @staticmethod def unpad( s ): """return s[0:-ord(s[-1])]""" return s def __init__(self, key): self.key = Cipher.md5sum(key) #the state of the counter callback self.cnter_cb_called = 0 self.secret = None def _reset_counter_callback_state( self, secret ): self.cnter_cb_called = 0 self.secret = secret def _counter_callback( self ): """ this function should be stateful """ self.cnter_cb_called += 1 return self.secret[self.cnter_cb_called % Cipher.BS] * Cipher.BS def encrypt(self, raw): secret = os.urandom( Cipher.BS ) #random choose a "secret" which is not secret self._reset_counter_callback_state( secret ) cipher = AES.new( self.key, AES.MODE_CTR, counter = self._counter_callback ) raw_padded = Cipher.pad( raw ) enc_padded = cipher.encrypt( raw_padded ) return secret+enc_padded #yes, it is not secret def decrypt(self, enc): secret = enc[:Cipher.BS] self._reset_counter_callback_state( secret ) cipher = AES.new( self.key, AES.MODE_CTR, counter = self._counter_callback ) enc_padded = enc[Cipher.BS:] #we didn't encrypt the secret, so don't decrypt it raw_padded = cipher.decrypt( enc_padded ) return Cipher.unpad( raw_padded )
一些测试:
>>> from Cipher import Cipher>>> x = Cipher("this is key")>>> "a"==x.decrypt(x.encrypt("a"))True>>> "b"==x.decrypt(x.encrypt("b"))True>>> "c"==x.decrypt(x.encrypt("c"))True>>> x.encrypt("a")==x.encrypt("a")False #though the input is same, the outputs are different参考:http :
//packages.python.org/pycrypto/Crypto.Cipher.blockalgo-
module.html#MODE_CTR



