【问题标题】:How to use public-key encryption in Py4A scripts?如何在 Py4A 脚本中使用公钥加密?
【发布时间】:2013-06-11 20:42:31
【问题描述】:

我正在开发一个在 Android 手机上运行的 Py4a(SL4a 中的 Python)应用程序。 该应用程序收集一些敏感数据,然后使用 smtplib 模块通过电子邮件发送。 为了确保必要的保护,我需要加密该信息。 由于手机被认为是不安全的设备,我必须使用公钥加密,并且只有收件人的公钥应该存储在手机中。

标准的 Py4a 发行版包含两个支持公钥加密的包: sslgdata。 不幸的是,它们都没有提供现成的功能,允许我用私钥加密更长的信息。 好吧,我知道实际上我应该生成一个随机的临时对称密钥,用那个密钥加密我的信息,最后只用接收者的公钥加密这个密钥。但是,为了获得安全的解决方案,必须考虑一些细节......

所以我的问题来了。是否有任何简单的加密库,非常适合 Py4a(即基于 Py4a 中已有的加密库,如 ssl 和 gdata.Crypto),提供易于使用的公钥加密?

2013.06.13 更新

我在 Py4a 中使用 gdata 库进行了一些实验。 最后我得到了以下“快速而肮脏”的解决方案:

import gdata.tlslite.utils.keyfactory as rk
#Generate the recipient's RSA key
sec=rk.generateRSAKey(1024)
#obtain the publickey, which will be stored
#in the sender mobile phone
pubxml=sec.writeXMLPublicKey()
print pubxml
#Create the public key from XML
pub=rk.parseXMLKey(pubxml)
#
#Now lets simulate the sender
#It has only access to "pub" 
#
import gdata.tlslite.utils.PyCrypto_AES as sk
import gdata.tlslite.utils.cipherfactory as cf
#Generate random key and initioalization vectors
key=sk.getRandomBytes(32)
iv=sk.getRandomBytes(16)

#Here we should check if the key and iv are reasonable
#Now we accept them as they are

#Text to encrypt
txt1="Strictly secret unknown text!"
#Pad the text to the length N*16
padlen=16-(len(txt1) % 16)
if padlen:
   txt1=txt1.ljust(len(txt1)+padlen, " ")
#Create the AES key
ak=cf.createAES(key.tostring(),iv.tostring())
#Encrypt text
ctxt1=ak.encrypt(txt1)
#Encrypt key and initialization vector with recipients publickey
ckey1=pub.encrypt(key+iv)
#
# Now we simulate the recipient
# It has its secret key 'sec', and received encrypted key
# and iv from the sender in ckey1. It also receives ctxt1
#
pkey1=sec.decrypt(ckey1)
pkey=pkey1[0:32]
piv=pkey1[32:48]
# Now we decipher the text
pak=cf.createAES(pkey.tostring(),piv.tostring())
ptxt1=pak.decrypt(ctxt1)
# Print the deciphered text
print ptxt1

这个解决方案可能远非最佳,但至少有效。

【问题讨论】:

  • 一些 cmets:您应该使用适当的加密填充,您的库应该支持一个(PKCS#1/7 填充等)。无需加密 IV,您可以将其与密文一起发送。理想情况下,您应该使用具有不同密钥(或经过身份验证的加密,但可能不支持)的 HMAC 以确保密文未被篡改(Google 'padding oracle')。

标签: android encryption public-key-encryption sl4a


【解决方案1】:

由于手机是不安全的设备,因此您不能信任手机上计算的任何内容。如果您想安全地完成某事,请在您的服务器上进行。

至于您的问题,这就是公共密码学(至少是 RSA)的工作原理:您不能加密任何比密钥长的数据。没有图书馆的原因是这是不可能的。如果您需要安全的电子邮件,请使用 S/MIME 或 GPG,不要尝试重新发明轮子。另请注意,由于密钥需要在应用程序中,任何人都可以提取它并解密您的数据。如果您只想安全地发送数据,更好的方法可能是通过 HTTPS 发送数据。这样您就无需管理客户端密钥,并且您的数据将在传输过程中受到保护。

【讨论】:

  • 我同意,手机不安全。但是如果数据是在这个设备中收集的,我至少需要保护它们,当它们通过网络传输时。由于项目中的其他限制。这些数据不能通过专用服务器传输,必须以受保护的形式通过电子邮件发送。在我正在寻找的解决方案中,只有收件人的公钥存储在手机中——这根本不是秘密,也不会损害安全性。我希望我可以使用 GPG,但它似乎在 Py4A 中不可用。
  • 在任何情况下,您都无法单独使用公钥进行加密。您需要使用对称加密来加密数据,然后发送加密的密钥。做到这一点并非易事,因此更可取的是像 S/MIME 这样的既定解决方案。您始终可以直接使用 Java 或扩展 Py4a(假设可以)。
  • 这就是我在最初的问题中所说的“嗯,我知道实际上我应该生成一个随机的临时对称密钥,用那个密钥加密我的信息,最后只用接收者的公共密钥加密这个密钥钥匙。”非常感谢。我会继续寻找合适的解决方案。
  • 啊,我现在明白你的意思了。除了可能在 S/MIME 库中,您不会找到完全执行此操作的单个函数。如果您不能使用其他库,则必须从您拥有的原语(Cipher、PublicKey 等)构建它。
猜你喜欢
  • 2016-11-16
  • 1970-01-01
  • 2015-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
相关资源
最近更新 更多