def pbkdf2(password, salt, iterations, dklen=0, digest=None): if digest is None: digest = hashlib.sha256 dklen = dklen or None password = force_bytes(password) salt = force_bytes(salt) return pbkdf2_hmac(digest().name, password, salt, iterations, dklen)
def encode(self, password, salt): bcrypt = self._load_library() if self.digest is not None: password = binascii.hexlify( self.digest(force_bytes(password)).digest()) else: password = force_bytes(password) data = bcrypt.hash_valpw(password, salt) return "%s$%s" % (self.algorithm, force_text(data))
def verify(self, password, encoded_password): argon2 = self._load_library() algorithm, rest = encoded_password.split('$', 1) assert algorithm == self.algorithm try: return argon2.low_level.verify_secret( force_bytes('$' + rest), force_bytes(password), type=argon2.low_level.Type.I, ) except argon2.exceptions.VerificationError: return False
def encode(self, password, salt): argon2 = self._load_library() data = argon2.low_level.hash_val_secret( force_bytes(password), force_bytes(salt), time_cost=self.time_cost, memory_cost=self.memory_cost, parallelism=self.parallelism, hash_val_len=argon2.DEFAULT_hash_val_LENGTH, type=argon2.low_level.Type.I, ) return self.algorithm + data.decode('ascii')
def harden_runtime(self, password, encoded_password): _, data = encoded_password.split('$', 1) salt = data[:29] # BCrypt的salt的长度 rounds = data.split('$')[2] # 工作因子是对数,增加一倍的负载 diff = 2**(self.rounds - int(rounds)) - 1 while diff > 0: self.encode(password, force_bytes(salt)) diff -= 1
def __init__(self, server, params: dict): self._server = server self.key_prefix = force_bytes(params.get('KEY_PREFIX', b'')) self.default_timeout = params.get("DEFAULT_TIMEOUT", 300) self._options = params.get('OPTIONS', {}) self._serializer = import_module( params.get('SERIALIZER', DEFAULT_SERIALIZER)).Handler() self._compressor = import_module( params.get('COMPRESSOR', DEFAULT_COMPRESSOR)).Handler() app_closed.connect(self.close)
def aes(app, length=16, allowed_chars=None): """ AES key """ if length not in (16, 24, 32): raise CommandError("The key length can only be 16, 24 or 32") if allowed_chars is None: allowed_chars = string.digits + string.ascii_letters + string.punctuation key = get_random_string(length=length, allowed_chars=allowed_chars) key_bytes = force_bytes(key) aes_key = base64.urlsafe_b64encode(key_bytes).rstrip(b"=") print("AES KEY:", aes_key)
def pbkdf2(password, salt, iterations, dklen=0, digest=None): assert iterations > 0 if not digest: digest = hashlib.sha256 password = force_bytes(password) salt = force_bytes(salt) hlen = digest().digest_size if not dklen: dklen = hlen if dklen > (2**32 - 1) * hlen: raise OverflowError('dklen too big') L = -(-dklen // hlen) r = dklen - (L - 1) * hlen hex_format_string = "%%0%ix" % (hlen * 2) inner, outer = digest(), digest() if len(password) > inner.block_size: password = digest(password).digest() password += b'\x00' * (inner.block_size - len(password)) inner.update(password.translate(hmac.trans_36)) outer.update(password.translate(hmac.trans_5C)) def F(i): u = salt + struct.pack(b'>I', i) result = 0 for j in range(int(iterations)): dig1, dig2 = inner.copy(), outer.copy() dig1.update(u) dig2.update(dig1.digest()) u = dig2.digest() result ^= _bin_to_long(u) return _long_to_bin(result, hex_format_string) T = [F(x) for x in range(1, L)] return b''.join(T) + F(L)[:r]
def encrypt(self, text): """ 对明文进行加密 :param text: 需要加密的明文 :return: """ from Crypto.Cipher import AES # 16位随机字符串添加到明文开头 text = get_random_string(length=16) + force_text( struct.pack("I", socket.htonl(len(text)))) + text # 使用自定义的填充方式对明文进行补位填充 text = pkcs7.encode(text) # 加密 allowed_chars = string.digits + string.ascii_letters + string.punctuation iv = get_random_string(length=16, allowed_chars=allowed_chars) cryptor = AES.new(self.key, self.mode, iv) cipher_text = cryptor.encrypt(text) # 加密后的字符串转化为16进制字符串 cipher_text = force_bytes(iv) + cipher_text return str2hex(cipher_text)
def decrypt(self, text): """ 对解密后的明文进行补位删除 :param text: 密文 :return: 删除填充补位后的明文 """ from Crypto.Cipher import AES cipher_text = hex2str(text) iv = cipher_text[:16] cryptor = AES.new(self.key, self.mode, iv) # 解密并去除16位随机字符串 plain_text = force_text(cryptor.decrypt(cipher_text[16:])[16:]) content = pkcs7.decode(plain_text) # pad = ord(plain_text[-1]) # # 去除16位随机字符串 # content = plain_text[16:-pad] msg_len = socket.ntohl(struct.unpack("I", force_bytes(content[:4]))[0]) msg_content = content[4:msg_len + 4] return msg_content
def dumps(self, value): return force_bytes(json_encode(value))
def make_key(self, key): return b"%b%b" % (self.key_prefix, force_bytes(key))
def encode(self, password, salt): assert salt == '' return hashlib.md5(force_bytes(password)).hexdigest()
def encode(self, password, salt): assert salt == '' hash_val = hashlib.sha1(force_bytes(password)).hexdigest() return 'sha1$$%s' % hash_val
def encode(self, password, salt): assert password is not None assert salt and '$' not in salt hash_val = hashlib.md5(force_bytes(salt + password)).hexdigest() return "%s$%s$%s" % (self.algorithm, salt, hash_val)
def verify(self, password, encoded_password): algorithm, data = encoded_password.split('$', 1) assert algorithm == self.algorithm encoded_password_2 = self.encode(password, force_bytes(data)) return constant_time_compare(encoded_password, encoded_password_2)
def make_key(self, key): if self._is_make_key: return b"%b%b" % (self.key_prefix, force_bytes(key)) return key
def constant_time_compare(val1, val2): return hmac.compare_digest(force_bytes(val1), force_bytes(val2))