TEE下的加密深度学习:PySyft pytorch Intel SGX 关于受信任执行环境的安全聚合

现在,世界创造的数字数据比我们想象的要多-在过去十年中,现有数据的90%以上已经生成。人工智能领域已充分利用了所有数据的价值。深度学习模型利用了越来越多的数据,不仅在各个领域提供了突破,而且还为许多公司提供了相关的应用程序。

在越来越大的数据集上训练这些模型对几家公司的基础架构构成了关键问题。考虑到这一点,基础架构问题的替代方法是云计算。这带来了许多好处,例如可伸缩性,移动性,可靠性,节省成本等。但是,这也给我们带来了有关安全性,隐私性和机密性的问题。基础设施所有者值得信赖吗?当我们谈论敏感数据时,如何保证应用程序的远程,安全和私有执行?解决此大问题的可能方法之一是在受信任的执行环境(TEE)中运行该应用程序。

但是什么是TEE?
简而言之,TEE是与操作系统并行运行的隔离处理环境。这提供了几个安全功能,例如程序/应用程序的隔离执行,其完整性以及机密性。存储在TEE中的数据和应用程序受到密码保护,并且安全地执行了应用程序之间或与用户之间的交互(即,不仅保护数据而且还保护与远程实体的通信),并且启用了受信任的设备标识和身份验证。

英特尔SGX-英特尔的TEE解决方案
对于希望为应用程序层提供额外的硬件辅助安全性的开发人员,英特尔®Software Guard eXtensions(也称为英特尔SGX)已成为首选的受信任执行环境。根据定义,英特尔SGX“是一组指令,可提高应用程序代码和数据的安全性,从而为它们提供更好的公开或修改保护。开发人员可以将敏感信息划分为安全区,而安全区是内存中执行的区域,具有更好的安全保护” 。

 

 

开发人员能够将其应用程序分为两部分-受信任和不受信任。受信任的部分是将在安全区域内执行的操作(安全硬件)。隔离区在CPU上解密,仅用于内部运行的代码和数据。这样,任何外部进程,甚至操作系统都无法读取安全区的内容(以其加密形式除外)。

 

我们的用例

  OpenMined致力于为私有,安全,多所有者控制的AI创建可访问的工具生态系统,从而使世界更加隐私。隐私保护分析始于对您看不到的数据进行分析。因此,它首先可以对您无法访问的机器内部的数据进行任意计算,也就是所谓的远程执行。我们扩展了PyTorch和Tensorflow的功能,使其能够在看不见的机器上远程运行。在我们的上下文中,远程执行的一种类型是联合学习。这使我们能够分散敏感数据的分散,而无需将其存储在中央服务器上。

  从这一点出发,我们能够阐述以下情形:

  两个数据所有者(Bob和Alice)-每个人都有不同的敏感数据集-想要用他们的数据训练一个模型,但由于它们是敏感的,因此两者都无法访问或查看对方的数据。无需将训练数据带入模型(中央服务器),我们需要将模型带入训练数据。

  模型所有者将模型发送给Bob和Alice,他们将使用其数据训练模型。

 

  在将模型发送回所有者之前,我们需要结合Bob和Alice的更新模型。为此,我们需要权重由受信任的安全工作者汇总。这样,只有安全工作者才能看到谁的重量来自谁。我们也许能够知道模型的哪些部分发生了更改,但是我们不知道哪个工作人员(鲍勃或爱丽丝)进行了哪些更改,从而创建了一层隐私。

  但这也引发了安全方面的问题。我们需要信任安全的工作者。该员工将位于何处,谁将拥有该员工的基础架构?我们如何保证数据的机密性和隐私性并进行安全汇总?

  这些问题与之前提出的问题非常相似,并且如我们所见,通过在安全硬件上运行聚合器的情况下使用英特尔SGX,我们能够确保基础架构所有者将无法访问Bob和Alice发送的数据,因为汇总将在飞地完成。

 

完成后,全局模型将被发送回模型的所有者。不会损害Alice和Bob数据的隐私。

 

PySyft + Intel SGX
为了使我们的用例成为可能,第一步是将PySyft(用于安全和私有深度学习的Python库)与Intel SGX集成在一起。英特尔提供SGX SDK,使开发人员可以更轻松地将其应用程序与该技术集成。该套件包括API,库,文档,示例源代码和工具。

在常规集成中,开发人员可以使用SDK API修改用C / C ++编写的源代码。

 

 

   这样,可以指定应用程序的哪些部分在安全区域中运行。但是,这在兼容性方面增加了限制。必须使用C / C ++编写应用程序才能使用SDK。令我们高兴的是,已经开发出了与其他平台(例如Graphene-SGX)兼容的技术。

  Graphene-SGX

“ Graphene是一种轻量级的LibOS,旨在运行具有最低主机要求的单个应用程序。Graphene可以在隔离的环境中运行应用程序,其好处可与在虚拟机中运行完整的操作系统相媲美–包括来宾自定义,易于移植到不同的操作系统,以及流程迁移。”

  借助Intel SGX支持,Graphene可以以最小的移植工作来保护硬件加密的内存区域中的关键应用程序,并保护应用程序免受恶意系统堆栈的攻击。它在英特尔内部运行未修改的应用程序 SGX支持动态加载的库,运行时链接,多进程抽象和文件身份验证。

  为了提高安全性,请在不受信任的主机接口上执行加密和语义检查。开发人员提供了一个清单文件来配置应用程序环境和隔离策略,其余的由Graphene自动完成。

借助Graphene,与Intel SGX的集成变得简单,如下所示:

 

首先,我们创建了清单文件,该文件定义了隔离环境和策略,如上所述。 Graphene将使用PAL(平台适配层)作为加载程序来引导库OS中的应用程序。要启动Graphene,PAL必须以可执行文件的形式运行,并带有程序名称和清单文件(从命令行中提供)。

PySyft脚本
现在,让我们看一下将用于实验的脚本。让我们使用虚拟工作者的可信聚合示例。

我们将首先导入要使用的内容,然后创建hook。
import torch
import syft as sy
from torch import nn, optim

hook = sy.TorchHook(torch)
我们还将创建两个工作人员Bob和Alice(将成为我们的数据所有者),以及第三个工作人员Secure Worker,在其中执行模型平均
bob = sy.VirtualWorker(hook, id="bob")
alice = sy.VirtualWorker(hook, id="alice")
secure_worker = sy.VirtualWorker(hook, id="secure_worker")
例如,我们将有一个玩具数据集。它的一部分属于Alice,另一部分属于Bob。
data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)
target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)

bobs_data = data[0:2].send(bob)
bobs_target = target[0:2].send(bob)

alices_data = data[2:].send(alice)
alices_target = target[2:].send(alice)

现在,我们初始化模型并将其发送给Bob和Alice进行更新。

model = nn.Linear(2,1)

bobs_model = model.copy().send(bob)
alices_model = model.copy().send(alice)

bobs_opt = optim.SGD(params=bobs_model.parameters(),lr=0.1)
alices_opt = optim.SGD(params=alices_model.parameters(),lr=0.1)

下一步是我们的训练脚本。

与通过安全平均进行联合学习的常规做法一样,每个数据所有者首先在本地对模型进行几次迭代训练,然后再对模型进行平均。

for i in range(10):

    # Train Bob's Model
    bobs_opt.zero_grad()
    bobs_pred = bobs_model(bobs_data)
    bobs_loss = ((bobs_pred - bobs_target)**2).sum()
    bobs_loss.backward()

    bobs_opt.step()
    bobs_loss = bobs_loss.get().data

    # Train Alice's Model
    alices_opt.zero_grad()
    alices_pred = alices_model(alices_data)
    alices_loss = ((alices_pred - alices_target)**2).sum()
    alices_loss.backward()

    alices_opt.step()
    alices_loss = alices_loss.get().data
    
    print("Bob:" + str(bobs_loss) + " Alice:" + str(alices_loss))

当每个数据所有者拥有经过部分训练的模型时,就该以一种安全的方式将它们平均在一起。我们需要指示Bob和Alice将他们的更新模型发送给Secure Worker。

alices_model.move(secure_worker)
bobs_model.move(secure_worker)
最后,此训练纪元的最后一步是将鲍勃和爱丽丝的训练模型平均在一起,然后使用它来设置全局“模型”的值。
with torch.no_grad():
    model.weight.set_(((alices_model.weight.data + bobs_model.weight.data) / 2).get())
    model.bias.set_(((alices_model.bias.data + bobs_model.bias.data) / 2).get())

最后,我们的训练脚本如下所示,现在我们只需要对此进行多次迭代!

for a_iter in range(iterations):
    
    bobs_model = model.copy().send(bob)
    alices_model = model.copy().send(alice)

    bobs_opt = optim.SGD(params=bobs_model.parameters(),lr=0.1)
    alices_opt = optim.SGD(params=alices_model.parameters(),lr=0.1)

    for wi in range(worker_iters):

        # Train Bob's Model
        bobs_opt.zero_grad()
        bobs_pred = bobs_model(bobs_data)
        bobs_loss = ((bobs_pred - bobs_target)**2).sum()
        bobs_loss.backward()

        bobs_opt.step()
        bobs_loss = bobs_loss.get().data

        # Train Alice's Model
        alices_opt.zero_grad()
        alices_pred = alices_model(alices_data)
        alices_loss = ((alices_pred - alices_target)**2).sum()
        alices_loss.backward()

        alices_opt.step()
        alices_loss = alices_loss.get().data
    
    alices_model.move(secure_worker)
    bobs_model.move(secure_worker)
    with torch.no_grad():
        model.weight.set_(((alices_model.weight.data + bobs_model.weight.data) / 2).get())
        model.bias.set_(((alices_model.bias.data + bobs_model.bias.data) / 2).get())
    
    print("Bob:" + str(bobs_loss) + " Alice:" + str(alices_loss))

最后,我们想确保我们得到的模型正确学习,因此我们将在测试数据集上对其进行评估。在这个玩具问题中,我们将使用原始数据,但在实践中,我们将希望使用新数据来了解模型将通用性推广到看不见的示例的程度。

preds = model(data)
loss = ((preds - target) ** 2).sum()


print(preds)
print(target)
print(loss.data)
该脚本基于PySyft教程“第4部分:模型平均化联合学习”

可信执行
有了清单文件和我们的程序,我们已经设法使用石墨烯通过Graphene的PAL加载程序安全地执行它。我们设置标志SGX = 1并以脚本参数pysyftexample.py和清单pysyft.manifest为参数。
SGX=1 ./pal_loader ./pysyft.manifest ./pysyftexample.py

作为输出,我们看到:

Bob:tensor(0.0338) Alice:tensor(0.0005)
Bob:tensor(0.0230) Alice:tensor(0.0001) 
Bob:tensor(0.0161) Alice:tensor(1.9244e-05) 
Bob:tensor(0.0115) Alice:tensor(1.9158e-07) 
Bob:tensor(0.0084) Alice:tensor(1.0417e-05) 
Bob:tensor(0.0062) Alice:tensor(2.2136e-05) 
Bob:tensor(0.0046) Alice:tensor(2.8727e-05) 
Bob:tensor(0.0034) Alice:tensor(3.0386e-05) 
Bob:tensor(0.0026) Alice:tensor(2.8821e-05) 
Bob:tensor(0.0020) Alice:tensor(2.5603e-05) 
tensor([[0.1221],
        [0.0984],
        [0.8764],
        [0.8526]], grad_fn=<AddmmBackward>)
tensor([[0.],
        [0.], 
        [1.],
        [1.]], requires_grad=True)
tensor(0.0616)

在此特定示例中,由于它是用于演示目的的单个脚本,因此在安全区域内(即使用Intel SGX)进行了具有安全聚合的整个模拟联合学习过程。这意味着在这种情况下,执行始终是加密的。在一个真实而具体的示例中,鲍勃(Bob)和爱丽丝(Alice)是不在飞地内奔跑的工人,而只是将进行汇总的安全工人。

工作人员之间的通信将通过TLS直接进行,而聚合器将在此运行。 可在OpenMined / sgx-experiments中找到用于此实验的文件。

未来的工作

使用英特尔SGX执行PySyft和PyTorch为我们打开了大门。从这里,我们可以致力于集成我们的项目和解决方案。

联合学习

为了使我们的用例切实可行,我们将在可信执行环境中执行网格节点作为下一个目标。这样,我们就可以告诉节点从安全区外部做什么,并在使用PyGrid的联合学习过程中将该节点用作我们的安全工作者和可信赖的聚合器。我们从第一点开始,那里有一个始终被加密的脚本,我们将朝着将应用程序划分为必须在安全区内外运行的部分进行移动。由此,我们可以改善时间和性能,毕竟执行保密性的保证是昂贵的,而我们提供的保证越多,成本就越高。必须在隐私和性能之间进行权衡

远程认证
英特尔提供了一项高级功能,允许硬件实体或硬件和软件的组合获得远程提供商或生产商的信任。

远程证明允许远程提供者(也称为依赖方)对软件正在运行具有增强的信心:

在飞地内
在最新安全级别(也称为可信计算库[TCB]版本)的完全更新的英特尔®Software Guard Extension(Intel®SGX)系统上
证明结果提供:

被证明软件的身份
未测量状态的详细信息(例如执行模式)
评估可能的软件篡改
在飞地成功地向答辩方证明自己之后,可以在两者之间建立加密的通信通道。可以将诸如凭证或其他敏感数据之类的机密直接提供给飞地。

实施远程证明的重要性在于证明要求保护的飞地确实在真正的SGX硬件内部运行,而不是某些(受对手控制的)SGX模拟器。

 

  •  

imp

发布了30 篇原创文章 · 获赞 74 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/ruiyiin/article/details/105584358
今日推荐