1. 遇到的问题
最近在参考DTPKC复现记录这篇文章去复现经典同态加密算法时,发现charm库是需要linux环境的,这对于面向pycharm编程的我十分不友好,在自己的虚拟机上成功配置好charm后(个人参考的这篇文章),我开始思考能不能在windos端连接虚拟机上的python解释器呢。
2. 使用pycharm进行连接
这里我先展示一下在虚拟机端的运行结果:
在windos端显然是找不到库的:
最近在阅读pycharm连接虚拟机这篇文章的时候,我突然意识到,我可以直接去导入虚拟机端的python这样就可以在windos上编程了。
在pycharm-设置-Python解释器里我们会看见我们的解释器以及内置的包的情况,在右上角可以选择SSH远程导入python。
直接点击连接输入虚拟机的ip(输入指令ifconfig,从ens33或是ens32网卡中读取IPV4的地址,找不到ens网卡可以参考这篇文章)以及用户名(输入who),具体效果见下图:
再输入用户的登录密码就可以了。
连接测试成功。
注意不要选创建虚拟环境(虚拟环境会新创一个空的解释器),选择系统解释器才可以导入虚拟机段的charm库。
导入成功,(2)是因为我之前已经成功导入过了,可以看见charm-crypto库已经导入了。
代码也成功运行了。
3.附上测试用的代码
from charm.toolbox.integergroup import IntegerGroup
from charm.schemes.pkenc.pkenc_rsa import RSA_Enc, RSA_Sig
from charm.core.math.integer import integer, randomBits, random, randomPrime, isPrime, encode, decode, hashInt, bitsize, \
legendre, gcd, lcm, serialize, deserialize, int2Bytes, toInt
class DTPKC():
def __init__(self, secparam=128):
# 选取两个大素数p和q
self.p, self.q = randomPrime(secparam, True), randomPrime(secparam, True)
# 计算p和q的一半
self.pp = (self.p - 1) / 2
self.qq = (self.q - 1) / 2
# 计算N和N^2
self.N = self.p * self.q
self.N2 = self.N ** 2
# 计算λ
self.lamda = lcm(self.p - 1, self.q - 1) / 2
# 随机选择a,并计算g为负元
self.a = random(self.N2)
tmp = self.a ** (2 * self.N)
self.g = (int(self.N2) - int(tmp)) % self.N2
self.mk = self.lamda
def GetMK(self):
return self.mk
def KeyGen(self):
# 随机生成θ,并计算h
theta = random(self.N / 4)
h = self.g ** (theta) % self.N2
# 公钥pk为(N, g, h),私钥sk为θ
pk = {"N": self.N, "g": self.g, "h": h}
sk = theta
return pk, sk
def Encrypt(self, pk, plaintext):
# 加密过程
r = random(self.N / 4)
T1 = int(pk["h"] ** (r)) * int(1 + plaintext * self.N) % self.N2
T2 = pk["g"] ** (r) % self.N2
ciphertext = {"T1": T1, "T2": T2}
return ciphertext
def Decrypt(self, ciphertext, sk):
# 使用私钥sk解密
T1 = ciphertext["T1"]
T2 = ciphertext["T2"]
tmp = (T1 / (T2 ** sk)) % self.N2
m = (int(tmp) - 1) / self.N
return m
def DecryptMK(self, ciphertext, mk):
# 使用主密钥mk解密
tmp = ciphertext["T1"] ** (mk) % self.N2
mk = mk % self.N
mk_1 = mk ** (-1)
m = ((int(tmp) - 1) / self.N) * int(mk_1) % self.N
return integer(m)
def SplitMK(self, mk):
# 主密钥拆分
mk = mk % self.N
mk_1 = mk ** (-1)
tmp = int(mk) * int(int(mk_1) % self.N2)
modulus = int(mk) * int(self.N2)
s = tmp % modulus
lamda1 = random(s)
lamda2 = s - int(lamda1)
return integer(lamda1), integer(lamda2)
def PSDec1(self, ciphertext, lamda1):
# 部分解密一
ct1 = ciphertext["T1"] ** (lamda1)
return ct1
def PSDec2(self, ciphertext, lamda2, ct1):
# 部分解密二
ct2 = ciphertext["T1"] ** (lamda2)
T = ct1 * ct2
m = (int(T) - 1) / int(self.N)
return integer(int(m))
if __name__ == "__main__":
dt_pkc = DTPKC()
mk = dt_pkc.GetMK()
print("mk is:", mk)
pk, sk = dt_pkc.KeyGen()
print("------------------------------")
print("pk is:", pk, "sk is:", sk)
plaintext = 1024
print("------------------------")
print("plaintext is:", plaintext)
ciphertext = dt_pkc.Encrypt(pk, 1024)
print("------------------------")
print("ciphertext is:", ciphertext)
m1 = dt_pkc.Decrypt(ciphertext, sk)
print("-------------------------")
print("使用sk解密后的结果为:", m1)
m2 = dt_pkc.DecryptMK(ciphertext, mk)
print("-------------------------")
print("使用mk解密后的结果为:", m2)
lamda1, lamda2 = dt_pkc.SplitMK(mk)
print("-------------------------")
print("lamda1 is:", lamda1)
print("lamda2 is:", lamda2)
print("现在使用lamda1和lamda2进行解密:")
ct1 = dt_pkc.PSDec1(ciphertext, lamda1)
print("-------------------------")
print("中间结果为:", ct1)
print("-------------------------")
m3 = dt_pkc.PSDec2(ciphertext, lamda2, ct1)
print("使用lamda1和lamda2解密后的结果为:", m3)