def decrypt(self, data): if not self.check_result: self.logger.error('使用AES256解密加密数据失败,原因:' + self.err_msg) return (False, self.err_msg) if not self.b_password or self.b_password is None: return (False, "加密密码为空") data = obj2bytes(data) if data[0]: data = data[1] else: return data ciphertext = unhexlify(data) b_salt, b_cryptedHmac, b_ciphertext = ciphertext.split(b"\n", 2) b_salt = unhexlify(b_salt) b_ciphertext = unhexlify(b_ciphertext) b_key1, b_key2, b_iv = self._gen_key_initctr(self.b_password, b_salt) hmacDecrypt = HMAC.new(b_key2, b_ciphertext, SHA256) if not self._is_equal(b_cryptedHmac, bytes2string(hmacDecrypt.hexdigest())): self.logger.error('使用AES256解密加密数据失败,原因:密码错误') return (False, "解密失败,密码错误") ctr = Counter.new(128, initial_value=int(b_iv, 16)) cipher = AES.new(b_key1, AES.MODE_CTR, counter=ctr) b_plaintext = cipher.decrypt(b_ciphertext) padding_length = b_plaintext[-1] b_plaintext = b_plaintext[:-padding_length] return self._handle_result(b_plaintext)
def __init__(self, password, header): ''' 对数据/文件进行加解密 :parm password : 加解密密码 :return 返回一个元组,(是否执行成功,成功加密数据/失败原因) ''' self.logger = logging.getLogger("security") self.password = password self.this_cipher = AES256_Algorithm(self.password) result = obj2bytes(header) if result[0]: temp = result[1] else: temp = string2bytes(header) self.b_header = temp result = obj2string(header) if result[0]: temp = result[1] else: temp = bytes2string(header) self.header = temp
def _is_encrypt(self, data): ''' 判断加密数据是否使用使用非本系统加解密算法加密的 ''' ciphertext_list = self._split_header(data) temp_header = ciphertext_list[0] result = obj2bytes(temp_header) if result[0]: temp = result[1] else: temp = string2bytes(temp_header) b_header = temp result = obj2string(temp_header) if result[0]: temp = result[1] else: temp = bytes2string(temp_header) header = temp if b_header in self.b_header or header in self.header: return True else: return False
def encrypt(self, data): if not self.check_result: self.logger.error('使用AES256解密加密数据失败,原因:' + self.err_msg) return (False, self.err_msg) if not self.b_password or self.b_password is None: return (False, "加密密码为空") data = obj2bytes(data) if data[0]: b_plaintext = data[1] else: return data b_salt = os.urandom(32) b_key1, b_key2, b_iv = self._gen_key_initctr(self.b_password, b_salt) bs = AES.block_size padding_length = (bs - len(data) % bs) or bs temp = obj2bytes(padding_length * chr(padding_length)) if temp[0]: temp = temp[1] else: return temp b_plaintext += temp ctr = Counter.new(128, initial_value=int(b_iv, 16)) cipher = AES.new(b_key1, AES.MODE_CTR, counter=ctr) b_ciphertext = cipher.encrypt(b_plaintext) hmac = HMAC.new(b_key2, b_ciphertext, SHA256) b_temp_ciphertext = b'\n'.join([ hexlify(b_salt), string2bytes(hmac.hexdigest()), hexlify(b_ciphertext) ]) b_new_ciphertext = hexlify(b_temp_ciphertext) return self._handle_result(b_new_ciphertext)
def __init__(self, password): self.logger = logging.getLogger("ansible") self.password = password from library.config.security import vault_header tmp_header = vault_header + ';date:' + str(time.time()) self.vault_header = tmp_header result = obj2bytes(tmp_header) if result[0]: temp_header = result[1] else: temp_header = string2bytes(tmp_header) self.b_vault_header = temp_header self.cipher = Using_AES256(self.password, self.b_vault_header)
def _split_header(self, data): ''' 对加密数据进行分割,分为加密头和加密数据 :parm data :需要分割的加密数据 ''' result = obj2bytes(data) if result[0]: data = result[1] else: data = string2bytes(data) b_data = data.split(b'\n') b_header = b_data[0].strip() b_ciphertext = b''.join(b_data[1:]) return (b_header, b_ciphertext)
def _format_output(self, data): ''' 对加密数据进行格式化,仅用于写入文件 :parm ciphertext :需要格式化的数据 ''' result = obj2bytes(data) if result[0]: b_ciphertext = result[1] else: b_ciphertext = string2bytes(data) b_new_ciphertext = [self.b_header] b_new_ciphertext += [ b_ciphertext[i:i + 80] for i in range(0, len(b_ciphertext), 80) ] b_new_ciphertext += [b''] b_new_ciphertext = b'\n'.join(b_new_ciphertext) return b_new_ciphertext
def _handle_ciphertext(self, data=None, filename=None): ''' 对加密数据/文件内容的头部进行判断使用哪种方式加密 data或者filename其中一个可以为空,至少一个不能为空 如果两个均不为空,默认使用filename :parm data:加密数据 filename:加密文件 :return 算法或者False ''' if data is None and filename is None: self.logger.error('解密ansible加密数据时出错,原因:参数data和filename不能同时为空') return (False, False, '参数data和filename不能同时为空') if filename is not None: result = read_file(filename) if result[0]: data = result[1] else: if data is None: self.logger.error('解密ansible文件' + filename + '时出错,无法读取文件,原因:' + result[1]) return (False, False, '无法读取文件') result = obj2bytes(data) if result[0]: b_data = result[1] else: b_data = string2bytes(data) b_data = b_data.split(b'\n') b_vault_header = b_data[0].strip() b_ciphertext = b''.join(b_data[1:]) vault_header = obj2string(b_vault_header)[1] if b_vault_header in self.b_vault_header: #这是自定义加密数据 self.logger.info('解密ansible加密数据成功,注:加密数据使用本系统自定义方法加密的') return (True, True, b_data) elif re.search('ANSIBLE_VAULT;1.1;', vault_header): #这是ansible2.3版本加密数据 # return (False, True, data) #在ansible 2.3版本中,vault加密后头部为'$ANSIBLE_VAULT;1.1;AES256',其他版本未知 if vault_header == '$ANSIBLE_VAULT;1.1;AES256': #说明加密方式为AES256,自定义加密算法一直,直接使用自定义方式进行解密 data = self.b_vault_header + b'\n' + b_ciphertext result = obj2bytes(data) if result[0]: self.logger.info('解密ansible加密数据成功,注:加密数据使用ansible2.3版本加密的') return (True, False, result[1]) else: self.logger.error( '解密ansible加密数据时失败,原因:加密数据使用ansible2.3版本加密的,' + str(result[1])) return (False, True, data) else: self.logger.error('解密ansible加密数据时失败,原因:未知格式的加密方法') return (False, True, data) else: self.logger.error('解密ansible加密数据时失败,原因:未知格式的加密方法') return (False, False, '未知格式的加密数据')