【数据保护】微软开源数据保护项目Presidio-匿名器

news2025/1/9 14:51:17

Presidio是由微软维护的开源数据保护项目,其主要包含三个功能模块,分别是:

  • Presidio analyzer:该模块主要负责文本类数据敏感信息扫描。
  • Presidio anonymizer:该模块主要负责对已检测到的敏感实体进行脱敏处理。
  • Presidio image redactor:该模块主要利用OCR技术识别图片中敏感信息并进行脱敏处理。

anonymizer模块的设计图如下所示:

匿名器中主要包含两个功能类,分别是Anonymizers类和Deanonymizers。其中Anonymizers类主要负责对敏感数据实体进行脱敏操作。Deanonymizers主要负责对脱敏后的数据还原,例如对加密后的敏感数据解密。

对于匿名器的创建和使用可以参考【数据保护】微软开源数据保护项目Presidio-从入门到精通这篇文章对于匿名器的介绍。本篇文章主要介绍匿名器内置的脱敏操作以及敏感实体交叠情况下的判定。

匿名化

replace

将敏感数据实体替换成期望呈现的值。

参数:

  • new_value:将敏感数据替换成此参数给定的值。如果此参数没有传参,那么默认情况下使用敏感数据类型名替换,例如
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import RecognizerResult, OperatorConfig

text = "My name is Bond, James Bond"
engine = AnonymizerEngine()
result = engine.anonymize(
    text= text,
    analyzer_results=[
        RecognizerResult(entity_type="PERSON", start=11, end=15, score=0.8),
        RecognizerResult(entity_type="PERSON", start=17, end=27, score=0.8),
    ],
    operators={"PERSON": OperatorConfig("replace", {"new_value": "XXX"})},
)

print("替换前:", text)
print("替换前:", teresultxt)

执行结果:

替换前: My name is Bond, James Bond
替换后: My name is XXX, XXX

redact

删除敏感数据内容。

参数:无

from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import RecognizerResult, OperatorConfig

text = "My name is Bond, James Bond"
engine = AnonymizerEngine()
result = engine.anonymize(
    text= text,
    analyzer_results=[
        RecognizerResult(entity_type="PERSON", start=11, end=15, score=0.8),
        RecognizerResult(entity_type="PERSON", start=17, end=27, score=0.8),
    ],
    operators={"PERSON": OperatorConfig("redact")},
)

print("替换前:", text)
print("替换后:", result.text)

执行结果:

替换前: My name is Bond, James Bond
替换后: My name is , 

mask

将敏感数据内容替换为指定的字符。

参数:

  • chars_to_mask:应该替换的敏感数据长度;
  • masking_char:替换的字符;
  • from_end:是否从敏感内容的结尾开始替换;
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import RecognizerResult, OperatorConfig

text = "My name is Bond, James Bond, phone num is 212-555-5555"
engine = AnonymizerEngine()
result = engine.anonymize(
    text= text,
    analyzer_results=[
        RecognizerResult(entity_type="PHONE_NUMBER", start=42, end=54, score=0.8),
    ],
    operators={"PHONE_NUMBER": OperatorConfig("mask", {"chars_to_mask": 12, "masking_char": "*", "from_end": True})},
)

print("替换前:", text)
print("替换后:", result.text)

执行结果:

替换前: My name is Bond, James Bond, phone num is 212-555-5555
替换后: My name is Bond, James Bond, phone num is ************

hash

使用敏感数据的哈希值替换原有值。

参数:

  • hash_type:设置哈希算法,可以是sha256、sha512或者md5。默认情况下是sha256。
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import RecognizerResult, OperatorConfig

text = "My name is Bond, James Bond"
engine = AnonymizerEngine()
result = engine.anonymize(
    text= text,
    analyzer_results=[
        RecognizerResult(entity_type="PERSON", start=11, end=15, score=0.8),
        RecognizerResult(entity_type="PERSON", start=17, end=27, score=0.8),
    ],
    operators={"PERSON": OperatorConfig("hash", {"hash_type":"md5"})},
)

print("替换前:", text)
print("替换后:", result.text)

执行结果:

替换前: My name is Bond, James Bond
替换后: My name is 7a3b691731db2969498907b960183633, 0a363424ef5ceaa17d33dfe4c545d7f3

encrypt

使用给定的Key对敏感数据加密后替换原有数据内容。

参数:

  • key:一段字符串作为key。
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import RecognizerResult, OperatorConfig

text = "My name is Bond, James Bond"
engine = AnonymizerEngine()
result = engine.anonymize(
    text= text,
    analyzer_results=[
        RecognizerResult(entity_type="PERSON", start=11, end=15, score=0.8),
        RecognizerResult(entity_type="PERSON", start=17, end=27, score=0.8),
    ],
    operators={"PERSON": OperatorConfig("encrypt", {"key":"WmZq4t7w!z%C&F)J"})},
)

print("替换前:", text)
print("替换后:", result.text)

执行结果:

替换前: My name is Bond, James Bond
替换后: My name is QtVyESAGf1LKgHxIDF8XQK5j8l9Bue3+nb/aZP0Croo=, qMkcFpDb9NZpV1BM2NQtf6CiCXD+r5gi27SoAeMqDE4=

custom

用户自定义实现匿名函数并传入。

参数:

  • lambda:lamdba函数,要求自定义函数返回字符串。
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import RecognizerResult, OperatorConfig


def fake(x):
    return "fake"

text = "My name is Bond, James Bond"
engine = AnonymizerEngine()
result = engine.anonymize(
    text= text,
    analyzer_results=[
        RecognizerResult(entity_type="PERSON", start=11, end=15, score=0.8),
        RecognizerResult(entity_type="PERSON", start=17, end=27, score=0.8),
    ],
    operators={"PERSON": OperatorConfig("custom", {"lambda":fake})},
)

print("替换前:", text)
print("替换后:", result.text)

执行结果:

替换前: My name is Bond, James Bond
替换后: My name is fake, fake

keep

不对敏感数据内容更改。

参数:无

from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import RecognizerResult, OperatorConfig


text = "My name is Bond, James Bond"
engine = AnonymizerEngine()
result = engine.anonymize(
    text= text,
    analyzer_results=[
        RecognizerResult(entity_type="PERSON", start=11, end=15, score=0.8),
        RecognizerResult(entity_type="PERSON", start=17, end=27, score=0.8),
    ],
    operators={"PERSON": OperatorConfig("keep")},
)

print("替换前:", text)
print("替换后:", result.text)

执行结果:

替换前: My name is Bond, James Bond
替换后: My name is Bond, James Bond

去匿名化

decrypt

对已经经过加密的敏感数据执行解密操作。

参数:

  • key:一段字符串作为key,此key与加密时key一样。
from presidio_anonymizer import AnonymizerEngine, DeanonymizeEngine
from presidio_anonymizer.entities import RecognizerResult, OperatorConfig
from presidio_anonymizer.operators import Decrypt


text = "My name is Bond, James Bond"
engine = AnonymizerEngine()
result = engine.anonymize(
    text= text,
    analyzer_results=[
        RecognizerResult(entity_type="PERSON", start=11, end=15, score=0.8),
        RecognizerResult(entity_type="PERSON", start=17, end=27, score=0.8),
    ],
    operators={"PERSON": OperatorConfig("encrypt", {"key":"WmZq4t7w!z%C&F)J"})},
)

print("替换前:", text)
print("替换后:", result.text)

deanonymize_engine = DeanonymizeEngine()
deanonymized_result = deanonymize_engine.deanonymize(
    text=result.text,
    entities=result.items,
    operators={"DEFAULT": OperatorConfig("decrypt", {"key": "WmZq4t7w!z%C&F)J"})},
)

print("解密后:", deanonymized_result.text)

执行结果:

替换前: My name is Bond, James Bond
替换后: My name is LvF+UsY9reo9dB4uXiS1yzIsM7TcDo1Yozaglz/rzIM=, IVhgF46vR2cwjXAyMa82Y1Go6M9JKq8lal6KxYZVIs8=
解密后: My name is Bond, James Bond

敏感数据重叠

在内容扫描时总会出现敏感内容之间出现重叠或者覆盖的情况,Presidio针对不同的情况执行不同策略。

无重叠

当敏感数据实体之间没有重叠,Presidio匿名器依据给定的匿名配置执行脱敏操作。

数据内容为:

My name is Inigo Montoya. You Killed my Father. Prepare to die. BTW my number is:
 03-232323.

假设只有"Inigo"被判定为NAME。

My name is <NAME> Montoya. You Killed my Father. Prepare to die. BTW my number is: 03-232323.

覆盖

当某个字符串符合多个识别器的识别特征时就会发生冲突,敏感数据应该如何进行脱敏处理?Presidio会比较敏感数据类型的置信度,并按照置信度最高类型对应的匿名配置进行匿名操作。假若置信度都相等,则Presidio任意选择一种进行脱敏操作。

数据内容为:

My name is Inigo Montoya. You Killed my Father. Prepare to die. BTW my number is:
 03-232323.

假设字符串"03-232323"既被识别成PHONE_NUMBER类型,且得分为0.7,又被识别成SSN类型,且得分为0.6,置信度高者胜出。

My name is Inigo Montoya. You Killed my Father. Prepare to die. BTW my number is: <PHONE_NUMBER>.

包含

某个敏感数据字符串被另一个敏感字符串包含且更长。Presidio将执行最长字符串对应的脱敏操作,忽略两个字符串扫描结果的置信度。

数据内容为:

My name is Inigo Montoya. You Killed my Father. Prepare to die. BTW my number is:
 03-232323.

假设"Inigo"被识别成FIRST_NAME类型,并且"Inigo Montoya"被识别成NAME类型,则使用字符串较长的类型对应的脱敏操作:

My name is <NAME>. You Killed my Father. Prepare to die. BTW my number is: 03-232323.

相交

两个敏感数据字符串出现相交,Presidio将会分别执行脱敏操作,并且脱敏结果同时替换原有数据。

数据内容为:

My name is Inigo Montoya. You Killed my Father. Prepare to die. BTW my number is: 03-232323.

假设字符串"03-2323"被识别成PHONE_NUMBER,"232323"被识别成SSN。

My name is Inigo Montoya. You Killed my Father. Prepare to die. BTW my number is: <PHONE_NUMBER><SSN>.

自定义匿名化操作

用户可以根据需求定制开发匿名化操作类型,并集成到匿名模块当中。

内置的匿名函数都在源码下的/presidio_anonymizer/operators文件加下,在这个文件夹下我们可以看到Presidio内置匿名化操作的实现。

用户需要常见自定义的匿名化操作类且继承Operator类型,并重写四个方法,分别是

operate、validate、operator_name和operator_type。其中operate方法完成匿名操作,validate方法用来解析用户传入的配置参数值类型是否合法。operator_name返回该匿名化类型名。operator_type返回固定的OperatorType.Anonymize。

最后将自定义类的名称添加到/presidio_anonymizer/operators/__init__.py中。

下面可以参考replace操作的实现:

class Replace(Operator):
    """Receives new text to replace old PII text entity with."""

    NEW_VALUE = "new_value"

    def operate(self, text: str = None, params: Dict = None) -> str:
        """:return: new_value."""
        new_val = params.get(self.NEW_VALUE)
        if not new_val:
            return f"<{params.get('entity_type')}>"
        return new_val

    def validate(self, params: Dict = None) -> None:
        """Validate the new value is string."""
        validate_type(params.get(self.NEW_VALUE), self.NEW_VALUE, str)
        pass

    def operator_name(self) -> str:
        """Return operator name."""
        return "replace"

    def operator_type(self) -> OperatorType:
        """Return operator type."""
        return OperatorType.Anonymize

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1960180.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习】语音,Tacotron 2 ,TTS合成

图1展示了Tacotron 2系统架构的框图。该系统包含两个主要部分&#xff1a;特征预测网络和WaveNet vocoder。以下是架构的详细说明&#xff1a; 特征预测网络 输入文本&#xff1a;系统从输入文本开始&#xff0c;经过一系列处理生成语音特征。字符嵌入层&#xff1a;输入的字…

ITSS三级认证需要多少钱?

信息技术服务标准&#xff08;ITSS&#xff09;认证是评估一个企业在信息技术服务领域能力的标准之一&#xff0c;它涵盖了从基础标准、支撑标准到基于业务的需求侧和供给侧标准的全面内容。 具体条件 独立法人地位&#xff1a;申请单位需要具有独立的法人地位&#xff0c;这是…

[leetcode hot 150]第二百三十题,二叉搜索树中第k小的元素

题目&#xff1a; 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 小的元素&#xff08;从 1 开始计数&#xff09;。 二叉搜索树&#xff08;BST&#xff09;有一个特性&#xff1a;对于树中的任何节点&#xff0c;其左…

lora网关到底能带多少设备,lora网关容量是多少?

引言&#xff1a;在推广LoRa模块的过程中&#xff0c;我频繁地遇到关于LoRa网关设备承载能力与容量的询问。为了更清晰地解答这些疑问&#xff0c;本文将深入探讨一个LoRa网关能支持的设备数量&#xff0c;以及这些数量如何受不同参数影响。 那么今天我们就详细的看下一个网关能…

如何使用Apache Web服务器提供自定义错误页面?

当您管理网站时&#xff0c;会花费大量时间来定制软件、运行软件以及调整布局和设计以符合您对网站外观的想法。通常我们只考虑网站中我们期望访问者看到的部分。不幸的是&#xff0c;有些常见页面可能会被忽略&#xff1a;错误页面。 错误页面 虽然理想情况下任何人都不应该在…

Codigger 之软件项目体检:提升企业软件交付质量的秘密武器

在当今竞争激烈的商业环境中&#xff0c;企业软件交付的质量直接关系到企业的市场竞争力和客户满意度。高质量的软件不仅能够满足用户需求&#xff0c;还能降低长期的维护成本&#xff0c;提高企业的运营效率。因此&#xff0c;提升软件交付质量已成为企业关注的焦点。Codigger…

【限免】频控阵雷达:概念、原理与应用【附MATLAB代码】

​微信公众号&#xff1a;EW Frontier QQ交流群&#xff1a;949444104 主要内容 PDA、FDA MATLAB代码 %---------------------------------------- %功能:FDA和相控阵天线方向图 %版本:ver1.0 %时间:2017.11.1 %--------------------------------------- clear all; clc; disp…

一文速通GIT版本管理与分支控制

目录 1、了解Git功能 2、第一次使用Git&#xff08;首次配置好&#xff0c;后续不用再操作&#xff09; 打开git后端 设置用户签名 结果 3、初始项目架构 创建本地新仓库并初始化 文件添加到本地仓库 a.文件添加缓存区 b.缓存区内容提交到本地仓库 c.改写提交的注释 …

【产品分析】作业帮

​基本信息 作业帮是目前国内最大的 K12 在线教育类 APP&#xff0c;致力于为全国中小学生提供全学段的学习辅导服务&#xff0c;其课程覆盖小学&#xff0c;初中&#xff0c;高中所有学科&#xff0c;并支持在线答题解题、一对一辅导、作文搜索、直播课、题库练习等众多功能&…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第六十三章 输入子系统实验

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

Rpi Zero W做的老头乐声控灯

祭图__|\0>历经各种尝试&#xff0c;最后选了docker 里装个rhasspy&#xff0c;配上paho-mqtt搞出了这个奇葩夜灯。各种曲折就不说了&#xff0c;直接分享捷径思路。 这个绿板子是respeaker hat with 2 mic 用的是seeed-voicecard&#xff0c;跟着github编译&#xff0c;不…

SM2p256v1椭圆曲线点加点减倍点python实现代码

首先给出SM2p256v1椭圆曲线的建议参数如下&#xff1a; default_ecc_table {n: FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123,p: FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF,g: 32c4ae2c1f1981195f9904466a39c9948fe30bbff266…

基于零极点配置的PID控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 PID控制器的基本形式 4.2 零极点配置原理 5.完整工程文件 1.课题概述 基于零极点配置的PID控制系统simulink建模与仿真&#xff0c;设置不同个数的零极点&#xff0c;对比PID控制器的控制输出效果。…

方天云智慧平台系统 GetCompanyItem SQL注入漏洞复现

0x01 产品简介 方天云智慧平台系统,作为方天科技公司的重要产品,是一款面向企业全流程的业务管理功能平台,集成了ERP(企业资源规划)、MES(车间执行系统)、APS(先进规划与排程)、PLM(产品生命周期)、CRM(客户关系管理)等多种功能模块,旨在通过云端服务为企业提供…

算法板子:模拟哈希表——哈希映射、哈希表中插入新值、拉链法处理冲突、查找一个数是否在哈希表中

由题意到x是[-1e9,1e9]&#xff0c;我们要将x映射到[0,1e5)这种映射过程可以使用哈希函数hash(x)将x映射到对应的坑位&#xff0c;并使用哈希表存储映射后的x&#xff0c;这里的存储我们选用拉链法将映射到同一个坑位的数串起来; 哈希表又称为散列表比如: hash(4)4%31&#xff…

全国产业园排名新看点:国际数字影像产业园再创新高

随着中国数字经济的快速发展&#xff0c;产业园区作为技术创新和产业聚集的核心区域&#xff0c;正不断涌现出新的活力和突破。树莓集团旗下所运营的国际数字影像产业园&#xff0c;以其卓越的运营模式和创新能力&#xff0c;成功跻身全国产业园区的前列&#xff0c;成为行业的…

Godot学习笔记7——Input单例与自定义单例

一、单例 单例是一个可以在任何脚本直接访问的对象&#xff0c;分为内置单例与自定义单例。内置单例不是节点&#xff0c;主要成员是各类Server&#xff0c;开发者可以使用它们直接控制游戏程序的图形与音效等内容。 我们可以在文档中查找“GlobalScope”获取相关内容&#x…

【Python学习手册(第四版)】学习笔记07-Python对象类型-字符串详解

个人总结难免疏漏&#xff0c;请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。 这篇文章是对Python对象类型-字符串的详解。内容较多需花1-2h阅读。如果你是0基础的初学者建议看这篇文章&#xff0c;对比其他教程会更加容易上手。 对字符串做了…

Java语言程序设计——篇十(1)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 接口介绍 接口概述接口定义接口的实现实战演练 &#x1f445;接口的继承实战演练实战演练 接口的类型常量实战演练 静态方法默认方法解决默认方…

一投就中不是梦,录取率>80%,最快1个月就见刊,计算机沾边就收,认可度还不低

本次模术狮精心整理5本期刊&#xff0c;最快1个月就见刊&#xff0c;计算机沾边就收&#xff0c;认可度还不低&#xff01; 1 Knowledge-Based Systems ▲ 图片来源&#xff1a;Knowledge-Based Systems官网 期刊简介&#xff1a;《Knowledge-Based Systems》是人工智能领域的…