白话同态加密

虽然同态加密即使现在听起来也很陌生,但是其实这个概念来自 1978 年,由 RSA 算法的发明者的 R 和 A 以及 Dertouzos 提出。具体的定义如下:

A way to delegate processing of your data, without giving away access to it.

翻译成人话就是传统的加密方法和数据处理方法是互斥的,比如我需要计算两个数字的和(1 和 2),如果加密了之后,就无法对密文进行计算;如果想要进行计算,就必须知道这两个数字是 1 和 2。如果数据拥有方和计算方是同一方,那么知道 1 和 2 没啥问题;但如果数据拥有方和计算方并非同一方,并且数据拥有方还不想让计算方知道这两个数字是 1 和 2,这个时候就是同态加密发挥作用的时候了。

同态加密将数据的处理和数据本身解耦了:计算方拿到的是加密之后的数字,但是依然可以相加,相加之后把结果告诉数据拥有方,最终数据拥有方解密就可以知道最终的计算结果。

同态加密的这个特点使得云服务厂商非常在意,因为这一举解决了用户担心云服务厂商窃取数据的担心(因为加密了除了计算没法做其他事情),并且因为加密计算本身耗费更多计算资源,还可以变相提高营收。

总结一下:同态加密使得数据可以在加密的状态下进行计算,至于支持什么计算,如何进行计算,我们接下来继续讲。

定义同态加密

先假设一个场景:我想要处理一大批数据,如果在本地用明文要 100 个小时,这个时间太长了,所以我需要借助云计算的力量。但是因为这批数据很敏感,包括了我从小到大每一分每一秒的心情和各类身体指标,我不希望云计算平台能够直接获取到,这样我就感觉自己没有隐私了,所以我需要使用同态加密,让云计算平台在加密的情况下计算(假设只需要 1 个小时),我拿到加密计算的结果再解密得到真实结果。那么问题来了,这个过程需要几步?

  1. 我在本地生成用来加密数据的 Key
  2. 我用 Key 和 Encrypt 算法加密本地的数据,记为 EncData = Encrypt(Key, Data)
  3. 我告诉云平台需要如何计算数据,记为函数 F()
  4. 云平台进行计算 Evaluate,即 Evaluate(F(), EncData) = Encrypt(Key, F(Data)),记为 ProEncData
  5. 云平台将 ProEncData 发回给我
  6. 我用密钥进行解密 Decrypt,得到 F(Data) = Decrypt(Key, ProEncData),也就是最终结果

在以上六个步骤中,至少有四个函数是必须的:

  1. 生成密钥的函数:本地执行,生成密钥
  2. Encrypt 函数:本地执行,加密数据,加密之后的数据不会暴露源数据的信息
  3. Evaluate 函数:用来执行用户给定的计算函数 F(),是唯一由云平台运行的函数
  4. Decrypt 函数:本地执行,解密数据

根据支持的 F() 的不同,同态加密分成了两类:

  1. Fully Homomorphic Encryption, FHE:这种方式下,任何 F() 都可以,只要这个算法能够被计算机实现即可。不过这个计算开销非常大,目前暂无实际应用。注:Gentry 在 2009 年给出过一个实现

  2. Somewhat Homomorphic Encryption, SWHE:这种方式下,只支持某些特定的

    F()

    (比如只支持加法/乘法,并且只能执行有限次数)。这个方案有比较大的限制,但也因此计算开销较小,已经可以在实际中使用

    1. 乘法:RSA, Elgamal
    2. 加法:Paillier

接下来我们会详细看看 Paillier 算法和 RSA 算法,对加法同态和乘法同态有更加深入的理解。

Paillier 算法

因为有了前面的分析,我们知道一个同态加密算法需要四个函数:密钥生成、加密、解密、同态运算,针对 Paillier 算法,我们一项一项来看一下。

这里我们也准备了不同语言版本的实例:

  1. Python 版
  2. Golang 版

注:实际实现的过程中,一般不会直接实现 gcd 和 lcm 函数,而是采用一些替代的计算,具体参考上面链接中的源码。

密钥生成

总共有如下几个步骤:

  1. 随机选择两个质数 p 和 q 满足 |p|=|q|=τ|p|=|q|=τ,这个条件保证了 p 和 q 的长度相等。
  2. 计算 N=pqN=pq 和 λ=lcm(p−1,q−1)λ=lcm(p−1,q−1),注:lcm 表示最小公倍数
  3. 随机选择 g∈Z∗N2g∈ZN2∗,满足 gcd(L(gλmodN2),N)=1gcd(L(gλmodN2),N)=1,注:gcd 表示最大公约数;Z 表示整数,下标表示该整数集合里有多少个元素;L(x)=x−1NL(x)=x−1N
  4. 公钥为 (N,g)(N,g)
  5. 私钥为 λλ

加密

对于任意整数 m∈ZNm∈ZN,任意选择随机数 r∈Z∗Nr∈ZN∗,密文 C=E(m)=gmrNmodN2C=E(m)=gmrNmodN2

解密

对于密文 C∈Z∗N2C∈ZN2∗,解密得到明文 m 的计算如下:

m=L(CλmodN2)L(gλmodN2)modNm=L(CλmodN2)L(gλmodN2)modN

加法同态

对于任意明文 m1,m2∈ZNm1,m2∈ZN,假设 E(m1)=gm1rN1modN2E(m1)=gm1r1NmodN2 和 E(m2)=gm2rN2modN2E(m2)=gm2r2NmodN2,有

E(m1)E(m2)=gm1+m2(r1r2)NmodN2=E(m1+m2modN)E(m1)E(m2)=gm1+m2(r1r2)NmodN2=E(m1+m2modN)

这个性质表明 Paillier 加密方案具有加法同态性。

RSA 算法

RSA 算法作为最为知名的非对称加密算法,想必大家都有一定的了解,这里我们仍然以针对密钥生成、加密、解密、同态运算四个步骤,一项一项来看一下。同样可以参考下面的代码实例:

  1. Python 版

密钥生成

  1. 随机找两个质数 P 和 Q,越大越安全,并计算乘积 n=P∗Qn=P∗Q。P 和 Q 的乘积的二进制位数代表 RSA 加密的位数,一般来说都要有 1024 或 2048 位。
  2. 计算 n 的欧拉函数 ϕ(n)ϕ(n),表示在小于等于 n 的正整数中,与 n 构成互质关系的数的个数。比如 1~8 中,和 8 互质的有 1,3,5,7,所以 ϕ(8)=4ϕ(8)=4,如果 p 和 q 为质数,那么他们的乘积的欧拉函数有一个特殊的性质,公式为 ϕ(n)=ϕ(P∗Q)=ϕ(P−1)ϕ(Q−1)=(P−1)(Q−1)ϕ(n)=ϕ(P∗Q)=ϕ(P−1)ϕ(Q−1)=(P−1)(Q−1)
  3. 选取 e,要大于 1 小于 ϕ(n)ϕ(n),并且 e 与 ϕ(n)ϕ(n) 要互质
  4. 计算出一个整数 d,使得 (ed−1) % ϕ(n)=0(ed−1) % ϕ(n)=0,即 e∗de∗d 除以 ϕ(n)ϕ(n) 的余数为 1,实际上转化为找到二元一次方程 ed+kϕ(n)=1ed+kϕ(n)=1 的一组解(求 d 和 k),具体使用的是扩展欧几里得算法

于是我们可以得到:

  • 公钥 (n, e)
  • 私钥 (n, d)

在这样的条件下,如果想要根据 n 和 e 算出 d,就只能暴力破解,位数越长,玻璃破解时间越长。

加密

我们现在有个这么几个关键的数值:n, e, d。要使用公钥 (n, e) 加密,首先要求被加密的数字必须是整数且小于 n(如果是字符串,可以逐个取 ascii 码或 unicode 值,并且中间用非数字和字母分割即可)。假设我们需要加密的数字是 A,则加密之后的 B 为(为了区别使用大写):

Ae % n=BAe % n=B

如果没有 d,那么是很难从 B 中恢复 A 的。

解密

如果我们拥有私钥 (n, d),那么对于 B,就可以通过下面的公式计算出 A:

Bd % n=ABd % n=A

乘法同态

相对 Paillier 来说还要更加简单一些,我们只要把两个加密后的数字相乘即可,代码片段如下:

print('接下来加密计算 2 x 20')
print('加密 2')
enc1 = rsa.core.encrypt_int(2, public_key.e, public_key.n)
print(enc1)
print('加密 20') # 40471062776583530669631608186743860028386032505372124150562694293213549812024
enc2 = rsa.core.encrypt_int(20, public_key.e, public_key.n)
print(enc2) # 16915103439566807805446086181091224947678993169521653470724152014464992293178 print('相乘')
result = enc1 * enc2
print(result) # 684572213175112282577113686759405066981454950839007710126450052851088805616753069318980764721622690261112227625923822693220128510206043466290770597572272 print('解密结果')
decrypt_result = rsa.core.decrypt_int(result, private_key.d, public_key.n)
print(decrypt_result) # 40

写在最后

这一讲我们结合实际的例子熟悉了同态加密,接下来我们会继续介绍联邦学习相关的底层技术,让大家知其然更知其所以然。

参考链接

相关文章

同态加密与 Paillier/RSA的更多相关文章

  1. Paillier同态加密实现

    一.C++(该方案只实现了加密以及解密) 1.git clone https://github.com/klei0229/paillier.git 2.下载GMP与NTL包: 下载版本以及操作参见ht ...

  2. 同态加密-Homomorphic encryption

    同态加密(Homomorphic encryption)是一种加密形式,它允许人们对密文进行特定的代数运算得到仍然是加密的结果,将其解密所得到的结果与对明文进行同样的运算结果一样.换言之,这项技术令人 ...

  3. RSA加密解密及RSA加签验签

    RSA安全性应用场景说明 在刚接触RSA的时候,会混淆RSA加密解密和RSA加签验签的概念.简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解 ...

  4. 加密解密 AES RSA MD5 SHA

    加密解密: 对称加密:加密和解密相同秘钥.常见算法:AES, XTEA, 3DES. 非对称加密: 公钥加密 私钥加密. 加密和解密秘钥不同.常见算法:RSA OpenSSL> genrsa - ...

  5. RSA加密解密及RSA签名和验证及证书

    RSA加密解密及RSA签名和验证及证书 公钥是给别人的 发送密文使用公钥加密 验证签名使用公钥验证 私钥是自己保留的 接受密文使用私钥解密 发送签名使用私钥签名 上述过程逆转是不行的,比如使用私钥加密 ...

  6. 【云安全与同态加密_调研分析(8)】同态加密技术及其应用分析——By Me

    ◆同态加密技术(Homomorphic Encryption, HE)及其应用◆ ◆加密方案◆ ◆应用领域◆ ◆厂商◆ ◆同态加密现有产品形态和工程实现◆ ◆参考链接◆ ◆备注(其他参考信息)◆ 同态 ...

  7. (转)对称加密与非对称加密,以及RSA的原理

    一 概述 二对称加密和非对称加密 对称加密 非对称加密 区别 三RSA原理 整数运算 同余运算 当模数为合数n时 当模数为质数p的时候 离散对数问题 RSA原理 一 , 概述 在现代密码学诞生以前,就 ...

  8. RSA加密解密及RSA签名和验证

    原文:RSA加密解密及RSA签名和验证 1.RSA加密解密: (1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)加密 (3)解密2.RSA签名和验证 (1)获取密钥,这里是 ...

  9. Paillier同态加密的介绍以及c++实现

    我们先来简短认识一下Paillier同态加密算法: 如果就这么按照定义来用最简朴的c++程序写 就像这样: #include <iostream> #include <math.h& ...

随机推荐

  1. C. Not Equal on a Segment(codeforces)

    C. Not Equal on a Segment time limit per test 1 second memory limit per test 256 megabytes input sta ...

  2. CRB and His Birthday(hdu 5410)

    CRB and His Birthday Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  3. Monkey工具之fastbot-iOS实践

    Monkey工具之fastbot-iOS实践 背景 目前移动端App上线后 crash 率比较高, 尤其在iOS端.我们需要一款Monkey工具测试App的稳定性,更早的发现crash问题并修复. 去 ...

  4. 带你熟悉鸿蒙轻内核Kconfig使用指南

    摘要:本文介绍了Kconfig的基础知识,和鸿蒙轻内核的图形化配置及进阶的使用方法. 本文分享自华为云社区<鸿蒙轻内核Kconfig使用笔记>,作者: zhushy. 1. Kconfig ...

  5. XSLT映射文件函数

    任何的编程语言或者是SQL语句都有内置的函数或方法,而强大灵活的xslt技术也是如此.熟练掌握XSLT的常用函数的用法,XSLT的应用将变得如此轻松,你会发现XSLT比想象中还要牛!以下是xslt数值 ...

  6. P4081 [USACO17DEC]Standing Out from the Herd P

    知识点: 广义 SAM 原题面 Luogu 「扯」 随便「口胡」一下居然「过」了. 比较考验「代码能力」,第一次感觉「大模拟」没有白写((( 还有这个「符号」实在是太「上头」了. 前置知识 在线构造广 ...

  7. Histogram Processing

    目录 HISTOGRAM EQUALIZATION 代码示例 HISTOGRAM MATCHING (SPECIFICATION) 其它 Gonzalez R. C. and Woods R. E. ...

  8. 【MySQL作业】分组查询 group by 子句——美和易思分组查询应用习题

    点击打开所使用到的数据库>>> 1.按照商品类型分组统计商品数量和平均单价,并按平均单价升序显示. -- 按照商品类型分组统计商品数量和平均单价,并按平均单价升序显示: select ...

  9. Java基础(八)——IO流3_对象流

    一.对象流 1.序列化与反序列化 序列化:将内存中的Java对象保存到磁盘中或通过网络传输出去. 反序列化:将磁盘文件中的对象还原为内存中的一个Java对象. 用途: (1)将对象保存到物理硬盘:比如 ...

  10. Spring @Component 注解的使用

    使用说明 这个注解用于声明当前的类是一个组件类,Spring 会通过类路径扫描来自动侦测和自动装配这些组件,创建一个个 bean 后,注册到 Spring 容器中. 带 @Component 注解的类 ...