java代码简单实现
import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.Random; public class RSATest { public static void main(String[] args) throws Exception{ // 1. 生成RSA密钥对 // 获取指定算法的密钥对生成器 KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); // 初始化密钥对生成器(指定密钥长度, 使用默认的安全随机数源) gen.initialize(512); // 随机生成一对密钥(包含公钥和私钥) KeyPair keyPair = gen.generateKeyPair(); // 获取 公钥 和 私钥 RSAPublicKey pubKey = (RSAPublicKey)keyPair.getPublic(); RSAPrivateKey priKey = (RSAPrivateKey)keyPair.getPrivate(); // 获得公私钥 和 公共模数 BigInteger E = pubKey.getPublicExponent(); BigInteger D = priKey.getPrivateExponent(); BigInteger N = pubKey.getModulus(); System.out.println("E:" + E); System.out.println("D:" + D); System.out.println("N:" + N); BigInteger m1 = BigInteger.valueOf(new Random().nextInt(Integer.MAX_VALUE)); BigInteger m2 = BigInteger.valueOf(new Random().nextInt(Integer.MAX_VALUE)); // 加密 BigInteger C1 = m1.modPow(E, N); BigInteger C2 = m2.modPow(E, N); // 密文相乘 BigInteger C = C1.multiply(C2).mod(N); // 解密 BigInteger Mc = C.modPow(D, N); // 验证 BigInteger val = m1.multiply(m2); System.out.println("原始数据数据m1:" + m1 + ",m2:" + m2); System.out.println("m1加密后数据C1:" + C1); System.out.println("m2加密后数据C2:" + C2); System.out.println("C:" + C); System.out.println("Mc:" + Mc); } }
python代码简单实现
import rsa import rsa.core # pip install rsa (public_key, private_key) = rsa.newkeys(256) print('1.密钥生成') print('生成公钥') print('public key:', public_key) print(public_key.n,public_key.e) print() print('生成私钥') print('private key:', private_key) print(private_key.n,private_key.d) print() print('2.加密') enc1 = rsa.core.encrypt_int(2, public_key.e, public_key.n) print('加密3 结果 enc1: ' + str(enc1)) enc2 = rsa.core.encrypt_int(20, public_key.e, public_key.n) print('加密15 结果 enc2: ' + str(enc2)) print() result = enc1 * enc2 print('3.同态运算') print('相乘 result=' + str(enc1) + ' * ' + str(enc2) + '=' + str(result)) print() decrypt_result = rsa.core.decrypt_int(result, private_key.d, public_key.n) print('4.解密:' + str(decrypt_result)) print()
② ElGamal算法
ElGamal算法是一种基于Diffie-Hellman离散对数困难问题的公钥密码算法,可实现公钥加密和数字签名功能,同时满足乘法同态特性。ElGamal是一种随机化加密算法,即使每次用相同密钥加密相同明文得到的密文结果也不相同,因此不存在与RSA算法类似的选择明文攻击问题,是ISO同态加密国际标准中唯一指定的乘法同态加密算法。
加法同态加密算法
Paillier算法是1999年提出的一种基于合数剩余类问题的公钥加密算法,也是目前最为常用且最具实用性的加法同态加密算法,已在众多具有同态加密需求的应用场景中实现了落地应用,同时也是ISO同态加密国际标准中唯一指定的加法同态加密算法。此外,由于支持加法同态,所以Paillier算法还可支持数乘同态,即支持密文与明文相乘。
python代码简单实现
import random import phe from phe import EncodedNumber, paillier from phe.util import invert, powmod, getprimeover, isqrt import numpy as np # test if __name__ == "__main__": public_key, private_key = paillier.generate_paillier_keypair(n_length=10) print('pub', public_key.g, public_key.n) print('priv', private_key.p, private_key.q) A=[3,32] print('A', A) enA=[public_key.encrypt(x) for x in A] print(enA[0].ciphertext(False)) print(enA[0].ciphertext(False).bit_length()) B=[4,16] print('B', B) enB=[public_key.encrypt(x) for x in B] print(enB[0].ciphertext(False)) print(enB[0].ciphertext(False).bit_length()) en=np.add(enA,enB) print(en[0].ciphertext(False)) print(en[0].ciphertext(False).bit_length()) for x in en: print(private_key.decrypt(x))
有限全同态加密算法
2005年提出的Boneh-Goh-Nissim方案是一种基于双线性映射的公钥密码方案,支持任意次加法同态和一次乘法同态运算。方案中的加法同态基于类似Paillier算法的思想,而一次乘法同态基于双线性映射的运算性质。由于双线性映射运算会使得密文所在的群发生变化,因此仅能支持一次乘法同态运算,但仍支持对乘法后的密文进一步作加法同态运算。
同态加密的优势
我们当前的技术体系,建立在密码学基础上,工程中会用到很多密码学组件,非对称加密、可交互加密等,在这层之上,构建了很多安全算子,例如同态加密、不经意传输、秘密分享等。
非全同态加密存在的问题
1.非通用计算
非通用计算标准,需要根据具体的问题双方来制定不同的计算标准。概括来说就是一事一协议,新的计算需要在合作各方去使用同一个协议。一事一协议这种非通用计算,使用当前密码学技术来构建算子在工程实践中并非理想的解决方案。
2.计算逻辑的暴露
计算逻辑暴露的问题跟一事一协议紧密相关,两个数据拥有方需要遵循同一协议来计算某些结果。例如一个数据拥有方想要跟对方比较一个统计值的大小,它需要告诉对方要用到一个比较大小的协议。对方确认自己拥有同样的协议之后,才可能执行比较操作。
这样的话,任何参与方的计算过程中,计算逻辑都会暴露给其他参与方,参与者无法对计算逻辑本身进行保护。虽然计算逻辑听起来并不重要,但实际上在真实的金融场景中,一些模型及方法的计算逻辑可能是公司的核心机密,所以计算逻辑暴露对隐私计算来说是一个很重要的问题。
3.多轮次交互
在进行多协议交互时,其网络通信和交换的频次也会更加频繁,就会对网络带宽、网速和网络的稳定性产生较高要求。
在一些金融场景中,参与方与金融机构之间往往通过专线连接信息系统,当数据传输量较大,交换频次非常多时,往往出现整个计算流程被拖得较慢。另外当网络交换频次非常多时,对网络稳定性要求就比较高,断连、延迟等网络波动可能会使计算过程出现失败。
4.可信执行环境
面对上述多轮次交互带来的网络带宽、网速和网络稳定性问题,我们能否采用涉及硬件级安全计算的解决方案,例如使用可信执行环境。在实际业务的方案推进这种可信执行环境落地过程中,施工方可能会遇到一些非技术类问题,实际业务的客户比较关心特殊硬件的成本与安全:
需要特殊硬件支持,部署成本高
可信性依赖于国外硬件厂商
金融机构通常自建处理大数据业务的计算集群,已经投入大量成本,如果要重建一个基于可信执行环境的集群,成本是巨大的。另外,目前可信环境的硬件厂商主要来自国外,例如英特尔、AMD等,仅仅基于厂商的描述,客户无法完全认可这套设备可信性,信任度较低。
所以当我们遇到这类场景,需要解决业务机密问题,同时不能采用可信计算环境的时候,全同态加密就体现出它的优势。
标准化进展
1.半同态加密标准化
2019年5月,国际标准化组织ISO发布了同态加密标准(ISO/IEC 18033-6:2019)。该标准仅涉及半同态加密,具体包含两种较为成熟的半同态加密机制:ElGamal乘法同态加密和Paillier加法同态加密,并规定了参与实体的参数和密钥生成、数据加密、密文数据解密、密文数据同态运算等步骤的具体过程。
2.全同态加密标准化
2017年7月,来自学术界、工业界和政界的相关领域研究人员组成了全同态加密标准化开放联盟HomomorphicEncryption.org,在微软研究院举办了首届全同态加密标准化研讨会,开始共同推进全同态加密标准草案的编写工作,并发布了全同态加密安全标准、API标准、应用标准三份白皮书。迄今为止,HomomorphicEncryption.org在三年内已举办五届全同态加密标准化会议,参与成员包括微软、三星SDS、英特尔、IBM、谷歌、万事达卡等企业,以及NIST、ITU等机构的代表和各大高校的学者。在标准化进展方面,HomomorphicEncryption.org已分别于2018年3月和11月发布和更新了全同态加密标准草案。
同态加密应用场景
目前,同态加密算法已在区块链、联邦学习等存在数据隐私计算需求的场景实现了落地应用。由于全同态加密仍处于方案探索阶段,现有算法存在运行效率低、密钥过大和密文爆炸等性能问题,在性能方面距离可行工程应用还存在一定的距离。因此,实际应用中的同态加密算法多选取半同态加密(如加法同态),用于在特定应用场景中实现有限的同态计算功能。
1. 外包计算
当用户有数据但没算力资源,可利用同态加密技术对其数据进行加密,依靠第三方云厂商的算力资源进行结果计算。这样在不泄露自己数据隐私的前提下得到了自己想要的结果数据。
2. 模型训练
在模型训练过程中,标签拥有方对自有标签加密后,传输给特征拥有方。由于全同态加密算法允许对密文进行无限次的加法和乘法运算,因此特征拥有方可在密文空间去执行整个训练算法,并将训练好之后的模型返回给特征任务方进行解密。
在该过程中只需要两轮网络通信,免除了一些频繁的网络交互。同时标签拥有方其模型训练完全自主可控,可以对模型进行灵活调整,而不需要与特征拥有方同时具有相同的协议,因此其计算逻辑也不会暴露。
3. 联合风控
在联合风控场景,数据提供方不希望自己的数据泄露给银行,同时银行也不希望自己的风控规则泄露给数据提供方。在这种情况下,可利用全同态加密对数据提供方的数据和银行风控规则进行加密处理,最后根据计算结构来判定是否放贷。
4. 金融工程
在金融工程场景,客户不愿意把自己的持仓泄露给券商,而券商也不愿意将他投入巨大资源的金融工程模型泄露给对方。在这种情况下,可利用全同态加密对客户持仓数据进行加密,作为券商金融工程模型的输入,最后将计算得到的模型结果进行解密来进行资本操作。