Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的RSA加密&;在JS中解密_Python_Encryption_Rsa_Pycrypto_Jsencrypt - Fatal编程技术网

python中的RSA加密&;在JS中解密

python中的RSA加密&;在JS中解密,python,encryption,rsa,pycrypto,jsencrypt,Python,Encryption,Rsa,Pycrypto,Jsencrypt,我对密码学一无所知。我想从服务器端生成RSA密钥对,并将其发送到所有客户端(浏览器)。但在此之前,我只是简单地用python加密数据,然后通过pubnub发送到index.html文件,并尝试用JavaScript对其进行解密,以此来测试该场景。问题是当我做加密的时候 random_generator = Random.new().read key = RSA.generate(1024, random_generator) print key.exportKey() #<--privat

我对密码学一无所知。我想从服务器端生成RSA密钥对,并将其发送到所有客户端(浏览器)。但在此之前,我只是简单地用python加密数据,然后通过pubnub发送到index.html文件,并尝试用JavaScript对其进行解密,以此来测试该场景。问题是当我做加密的时候

random_generator = Random.new().read
key = RSA.generate(1024, random_generator)
print key.exportKey() #<--private key
public_key = key.publickey()
print public_key.exportKey() #<--public key
msg = "hello"
enc_data = public_key.encrypt(msg, 32)
print '----ENCRYPTED DATA----'
enc = enc_data[0] 
我试着把它转换成

enc = base64.b64encode(enc_data[0])
而且发送时没有错误。但是JS decrypt方法没有得到任何结果

  var enc_from_python = $('#input').val();
  console.log("ENCRYPTED data:", enc_from_python);
  var decrypt = new JSEncrypt();
  decrypt.setPrivateKey($('#privkey').val());
  var uncrypted = decrypt.decrypt(enc_from_python);
  console.log(">>>",uncrypted);  //<-- this is None ! why ?
var enc_from_python=$('#input').val();
log(“加密数据:”,enc_from_python);
var decrypt=new JSEncrypt();
decrypt.setPrivateKey($('#privkey').val());
var uncrypted=decrypt.decrypt(来自python的enc_);

console.log(“>>>”,未加密)// 如果您使用
Crypto.Cipher.PKCS1\u v1\u 5
这是可能的

下面是python代码

我只使用Python3进行了测试,但我相信在Python2中使用
\uuuuu future\uuuu
导入时,它应该也能工作

from __future__ import unicode_literals, print_function  # python2
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64

private_key = """-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBANBOMQo9wX55+w1ijEaPoYRP2T4BOjoFv3ma0QWqYYQ8FH0z14Zc
B/jb0j2PWpyNcsUUBovj+yWxQnQohCck64kCAwEAAQJBAL4s9PbNpO9MfFkfBMSS
8zoyEDtcsYUxpDtojbandDpdXfvn5D279QaOVLb1C3DgQTTEmroYB8dbeZBc5YJC
2AECIQDqyUn68ehRcx/EyLMUB1IuckZBWCIApgfn7phgVwSwiQIhAOMgY4bN+xrx
UV15Ian4ZbkME1IbAvDPcWuNGHxdsaMBAiBoz0K/S44yDfp4lj+bCUmeglTqhrVn
JLcSymgrWa02QQIhAMJFvPvcilGkYl1atCHHt3LN0mTjd+N0/OXq3SvblIsBAiAc
8RzaV1GmjMEJxw9vM/tQwQg0kyAPlITMRXnwGA6E0A==
-----END RSA PRIVATE KEY-----"""

rsa = RSA.importKey(private_key)
cipher = PKCS1_v1_5.new(rsa)

def encrypt(msg):
    ciphertext = cipher.encrypt(msg.encode('utf8'))
    return base64.b64encode(ciphertext).decode('ascii')

def decrypt(msg):
    ciphertext = base64.b64decode(msg.encode('ascii'))
    plaintext = cipher.decrypt(ciphertext, b'DECRYPTION FAILED')
    return plaintext.decode('utf8')

ciphertext = encrypt('hello stackoverflow!')
print(ciphertext)
plaintext = decrypt(ciphertext)
print(plaintext)
明文“hello stackoverflow!”的密文输出示例:

在javascript中,原始代码应该可以工作。这里有一个简化的版本来演示这个特定的密文和专用rsa密钥的工作原理

const decrypt=()=>{
const privateKey=document.getElementById('private_key')。值
const cipherText=document.getElementById('cipherText')。值
const decrypt=new JSEncrypt()
解密.setPrivateKey(privateKey)
常量明文=解密。解密(密文)| |“解密失败”
document.getElementById('plaintext')。innerHTML=纯文本
}
document.querySelector('button')。addEventListener('click',decrypt)

解密
明文:

密文:
tZDRXXcf7ppbVr9JBHQ3+2K3GEOFL8BDMLT3HROQBGVFKNY+XISBVY5HYH2ALPAUDU2AE4ISLYRFBONZPGW==
私钥:
-----开始RSA私钥----- MIIBOwIBAAJBANBOMQo9wX55+w1ijapoyrp2t4bojofv3ma0qwyyq8fh0z14zc B/jb0j2PWpyNcsUUBovj+YWXQNQOHCCK64KCAWEAQJBAL4S9PBNPO9MFFKFBMSS 8zoyEDtcsYUxpDtojbandDpdXfvn5D279QaOVLb1C3DgQTTEmroYB8dbeZBc5YJC 2 ECIQDQYUN68EHRCX/EYLMUB1UCKZBWCIAPGFN7PHGVWSWIQIHAOGY4BN+xrx UV15Ian4ZbkME1IbAvDPcWuNGHxdsaMBAiBoz0K/S44yDfp4lj+bCUmeglTqhrVn JLCSYMGRWA02QQIHAMJFVPCILGKYL1ATCHHT3LN0MTJD+N0/OXQ3SVBLISBAIC 8RzaV1GmjMEJxw9vM/tQwQg0kyAPlITMRXnwGA6E0A== -----结束RSA私钥-----
根据算法实现的不同,python和javascript可能有点不同,但trueJSencrypt使用PKCS#1 v1.5填充,而python代码不使用任何填充(教科书中的RSA不好)。在应用RSA时,您犯了一个根本性的、彻底的错误:您从未传输私钥。它始终保留在生成它的一侧。加密数据的长度很好,需要加密的数据的长度必须小于密钥长度。但是你是用私钥签名而不是加密,对吗?查看整个身份验证方案可能是个好主意。如果使用非对称加密,则需要确保传递到浏览器的公钥或私钥是可信的。这不是一个通常可以做出的假设,因为任何类型的JavaScript代码都可以注入HTTP连接。你需要HTTPS(带TLS)来保护公钥不被更改,但是如果你有了HTTPS,你就不再需要JavaScript加密了。这是一个很好的解决方案,但是我想用公钥来解密数据。我正在通过RSA.generate生成密钥对,并将其传递给PKCS1_v1_5对象。但是JS无法使用公钥解密。@AnumSheraz无法使用公钥解密。您可能指的是数字签名,但数字签名意味着您需要拥有数据来源的公钥。看看这篇文章下面的图片,
import time
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub

from Crypto.PublicKey import RSA
from Crypto import Random
import base64

pnconfig = PNConfiguration()
pnconfig.subscribe_key = 'demo'
pnconfig.publish_key = 'demo'
channel = "my_channel" 
pubnub = PubNub(pnconfig)

def my_publish_callback(envelope, status):
    if not status.is_error():
        pass  # Message successfully published to specified channel.
    else:
        pass  # Handle message publish error. Check 'category' property to find out possible issue


time.sleep(1)
random_generator = Random.new().read
key = RSA.generate(1024, random_generator)
print key.exportKey() #<--private key
public_key = key.publickey()
print public_key.exportKey() #<--public key
msg = "hello"
enc_data = public_key.encrypt(msg, 32)
print '----ENCRYPTED DATA----'
#enc = enc_data[0]
enc = base64.b64encode(enc_data[0])

print enc        
#print type(enc_data[0])
print '----ENCRYPTED DATA----'
print  ''
print '----DECRYPTED DATA begin----'
print key.decrypt(enc_data[0])
print '----DECRYPTED DATA end----'      

pubnub.publish().channel(channel).message({"data": enc , "private": (key.exportKey()), "public" : (public_key.exportKey())}).async(my_publish_callback)         
<!doctype html>
<html>
  <head>
    <title>JavaScript RSA Encryption</title>
    <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jsencrypt/2.3.1/jsencrypt.min.js"></script>
    <script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.12.0.min.js"></script>
    <script type="text/javascript">

      // Call this code when the page is done loading.
      $(function() {
        pubnub = new PubNub({
          publish_key: 'demo',
          subscribe_key: 'demo'
        });  

        pubnub.subscribe({
            channels: ['my_channel']
        }); 

    pubnub.addListener({
        message: function(message) {
            var msg = message.message;
            console.log("msg:" + JSON.stringify(msg));

             if (msg.private){
                $("#privkey").val(msg.private);
             }

             if(msg.public){
                $("#pubkey").val(msg.public);
             }

             if(msg.data){
                $("#input").val(msg.data);
             }           
        }    
    })      

        // Run a quick encryption/decryption when they click.
        $('#testme').click(function() {
          var enc_from_python = $('#input').val();
          console.log("ENCRYPTED data:", enc_from_python);
          // Decrypt with the private key...
          var decrypt = new JSEncrypt();
          decrypt.setPrivateKey($('#privkey').val());
          var uncrypted = decrypt.decrypt(enc_from_python);
          console.log(">>>",uncrypted);  //<-- this is None ! why ?
          // Now a simple check to see if the round-trip worked.
          if (uncrypted == $('#input').val()) {
            alert('It works!!!');
          }
          else {
            alert('Something went wrong....');
          }
        });
      });
    </script>
  </head>
  <body>
    <label for="privkey">Private Key</label><br/>
    <textarea id="privkey" rows="15" cols="65">   </textarea><br/>
    <label for="pubkey">Public Key</label><br/>
    <textarea id="pubkey" rows="15" cols="65">    </textarea><br/>
    <label for="input">Text to decrypt:</label><br/>
    <textarea id="input" name="input" type="text" rows=4 cols=70>This is a test!</textarea><br/>
    <input id="testme" type="button" value="Decrypt Me!!!" /><br/>
  </body>
</html>
from __future__ import unicode_literals, print_function  # python2
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64

private_key = """-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBANBOMQo9wX55+w1ijEaPoYRP2T4BOjoFv3ma0QWqYYQ8FH0z14Zc
B/jb0j2PWpyNcsUUBovj+yWxQnQohCck64kCAwEAAQJBAL4s9PbNpO9MfFkfBMSS
8zoyEDtcsYUxpDtojbandDpdXfvn5D279QaOVLb1C3DgQTTEmroYB8dbeZBc5YJC
2AECIQDqyUn68ehRcx/EyLMUB1IuckZBWCIApgfn7phgVwSwiQIhAOMgY4bN+xrx
UV15Ian4ZbkME1IbAvDPcWuNGHxdsaMBAiBoz0K/S44yDfp4lj+bCUmeglTqhrVn
JLcSymgrWa02QQIhAMJFvPvcilGkYl1atCHHt3LN0mTjd+N0/OXq3SvblIsBAiAc
8RzaV1GmjMEJxw9vM/tQwQg0kyAPlITMRXnwGA6E0A==
-----END RSA PRIVATE KEY-----"""

rsa = RSA.importKey(private_key)
cipher = PKCS1_v1_5.new(rsa)

def encrypt(msg):
    ciphertext = cipher.encrypt(msg.encode('utf8'))
    return base64.b64encode(ciphertext).decode('ascii')

def decrypt(msg):
    ciphertext = base64.b64decode(msg.encode('ascii'))
    plaintext = cipher.decrypt(ciphertext, b'DECRYPTION FAILED')
    return plaintext.decode('utf8')

ciphertext = encrypt('hello stackoverflow!')
print(ciphertext)
plaintext = decrypt(ciphertext)
print(plaintext)
tZDRXXcf7ppbVr9JBHQ3+2k3geofl8BdDmLT3HRoqBGvfknY+xISbvy5hYH2alPAUDu2ae4iSYsLyRFBOnzpgw==