Пример #1
0
    def _is_equal(b_a, b_b):
        b_b = string2bytes(b_b)
        b_a = string2bytes(b_a)

        if not (isinstance(b_a, bytes) and isinstance(b_b, bytes)):
            return False

        if len(b_a) != len(b_b):
            return False

        result = 0
        for b_x, b_y in zip(b_a, b_b):
            result |= b_x ^ b_y

        return result == 0
Пример #2
0
    def _gen_key_initctr(cls, b_password, b_salt):
        # 16 for AES 128, 32 for AES256
        keylength = 32

        # match the size used for counter.new to avoid extra work
        ivlength = 16
        b_password = string2bytes(b_password)

        if HAS_PBKDF2HMAC:
            backend = default_backend()
            kdf = PBKDF2HMAC(algorithm=c_SHA256(),
                             length=2 * keylength + ivlength,
                             salt=b_salt,
                             iterations=10000,
                             backend=backend)
            b_derivedkey = kdf.derive(b_password)
        else:
            b_derivedkey = cls._create_key(b_password, b_salt, keylength,
                                           ivlength)

        b_key1 = b_derivedkey[:keylength]
        b_key2 = b_derivedkey[keylength:(keylength * 2)]
        b_iv = b_derivedkey[(keylength * 2):(keylength * 2) + ivlength]

        return b_key1, b_key2, hexlify(b_iv)
Пример #3
0
    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
Пример #4
0
    def _get_vault_pwd(self):
        '''
        获取vault密码,并初始化vault密码
        '''

        vault_pwd_file = self.options_dict.get('vault_password_file', False)
        ask_vault_pass = self.options_dict.get('ask_vault_pass', False)

        if ask_vault_pass:
            vault_password = ask_vault_pass
        else:
            if vault_pwd_file:
                this_path = os.path.realpath(
                    os.path.expanduser(vault_pwd_file))
                if os.path.exists(this_path):
                    mode = self.loader.is_executable(this_path)
                    result = read_file(this_path,
                                       mode=mode,
                                       sprfmt=b'\r\n',
                                       outfmt='bytes')
                    if result[0]:
                        vault_password = result[1]
                    else:
                        vault_password = None
                else:
                    vault_password = None
            else:
                vault_password = None

        if vault_password:
            b_vault_password = string2bytes(vault_password)
            self.loader.set_vault_password(b_vault_password)
            self.vault_password = vault_password
        else:
            self.vault_password = None
Пример #5
0
    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
Пример #6
0
    def __init__(self, b_password):
        '''
        使用AES256加解密数据
        '''

        self.check_result = check_module()
        self.logger = logging.getLogger("security")
        self.b_password = string2bytes(b_password)
        self.err_msg = "可能您的python3环境中,pycrypto模块版本太低或者没有安装,请升级/安装,请SSH登陆到服务器上,执行pip3 install pycrypto或者pip3 install --upgrade pycrypto"
Пример #7
0
    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)
Пример #8
0
    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)
Пример #9
0
    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)
Пример #10
0
    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
Пример #11
0
    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, '未知格式的加密数据')