travist / jsencrypt

A zero-dependency Javascript library to perform OpenSSL RSA Encryption, Decryption, and Key Generation.
http://www.travistidwell.com/jsencrypt
Other
6.64k stars 2.01k forks source link

There seems to be a problem with public key decryption #153

Open sceneNoLonger opened 5 years ago

sceneNoLonger commented 5 years ago

I want to use the private key to encrypt the server and the public key to decrypt the browser. However, using the public key to decrypt is problematic.

The chasing code finds that an exception occurs when the public key is decrypted, resulting in the return of false.

PKCS8 format used by my server, key length 2048

savs90 commented 5 years ago

Public key is used only for encryption. Private key can decrypt and encrypt both. The idea of RSA is not to be able to decrypt with the public key. The reason is that the public key contains only N and E and the private key have additional D which is a must for decryption.

more info: https://en.wikipedia.org/wiki/RSA_(cryptosystem)

So in conclusion i would say that this effect is by RSA design.

sceneNoLonger commented 5 years ago

Public key is used only for encryption. Private key can decrypt and encrypt both. The idea of RSA is not to be able to decrypt with the public key. The reason is that the public key contains only N and E and the private key have additional D which is a must for decryption.

more info: https://en.wikipedia.org/wiki/RSA_(cryptosystem)

So in conclusion i would say that this effect is by RSA design.

Thank you. If so, I will use the public key to encrypt on the server and the private key to decrypt in the browser.

Finally, thank you very much.

savs90 commented 5 years ago

It is not very good idea to use the private key in the browser. From the private key it is very easy to generate the public key and therefore there will be no point from the encryption . Also keep in mind that you dont even need the public key , because when you have the private key you can encrypt and decrypt with it .

sceneNoLonger commented 5 years ago

It is not very good idea to use the private key in the browser. From the private key it is very easy to generate the public key and therefore there will be no point from the encryption . Also keep in mind that you dont even need the public key , because when you have the private key you can encrypt and decrypt with it .

Is there a good way to solve this problem, such as providing a public key decryption method?

Because, as you said, then I will not be able to use RSA, if so, my interactive data will become public, obviously not what I want.

Therefore, if we can provide a JS public key decryption, I think it is better, JAVA language can be public key decryption, I think, JS language can also do it.

I've seen a framework provided by Google, named JSRSASIGN, which can decrypt through public key. However, it seems to conflict with JAVA. I can't parse the encrypted text with JAVA. Maybe its API is too powerful. I haven't found the right way. I prefer JSEncrypt because it's lightweight and interacts with JAVA.

The only disadvantage is that public key decryption is not possible. If it can be provided, it would be very good.

savs90 commented 5 years ago

It is not very good idea to use the private key in the browser. From the private key it is very easy to generate the public key and therefore there will be no point from the encryption . Also keep in mind that you dont even need the public key , because when you have the private key you can encrypt and decrypt with it .

Is there a good way to solve this problem, such as providing a public key decryption method?

Because, as you said, then I will not be able to use RSA, if so, my interactive data will become public, obviously not what I want.

Therefore, if we can provide a JS public key decryption, I think it is better, JAVA language can be public key decryption, I think, JS language can also do it.

I've seen a framework provided by Google, named JSRSASIGN, which can decrypt through public key. However, it seems to conflict with JAVA. I can't parse the encrypted text with JAVA. Maybe its API is too powerful. I haven't found the right way. I prefer JSEncrypt because it's lightweight and interacts with JAVA.

The only disadvantage is that public key decryption is not possible. If it can be provided, it would be very good.

First i want to say that sign/verify is the opposite process of crypt/decrypt. In signing you first use the math formula for decrypting with the private key and after that you use the public key to encrypt the result and get the plain text. So mathematically is possible but i don`t know if some does this.

The whole idea in RSA is to have two pairs of Keys. One pair for the client and one pair for the server(or other client). They exchange their public keys and encrypt the messages with them. This means:

  1. Client encrypt text with Server public key and send it to server
  2. Server receive encrypted text and decrypt it with his private key
  3. Server generate an answer and encrypt it with Client public key and send it to client
  4. Client receive the answer decrypt it with his private key.
sceneNoLonger commented 5 years ago

It is not very good idea to use the private key in the browser. From the private key it is very easy to generate the public key and therefore there will be no point from the encryption . Also keep in mind that you dont even need the public key , because when you have the private key you can encrypt and decrypt with it .

Is there a good way to solve this problem, such as providing a public key decryption method? Because, as you said, then I will not be able to use RSA, if so, my interactive data will become public, obviously not what I want. Therefore, if we can provide a JS public key decryption, I think it is better, JAVA language can be public key decryption, I think, JS language can also do it. I've seen a framework provided by Google, named JSRSASIGN, which can decrypt through public key. However, it seems to conflict with JAVA. I can't parse the encrypted text with JAVA. Maybe its API is too powerful. I haven't found the right way. I prefer JSEncrypt because it's lightweight and interacts with JAVA. The only disadvantage is that public key decryption is not possible. If it can be provided, it would be very good.

First i want to say that sign/verify is the opposite process of crypt/decrypt. In signing you first use the math formula for decrypting with the private key and after that you use the public key to encrypt the result and get the plain text. So mathematically is possible but i don`t know if some does this.

The whole idea in RSA is to have two pairs of Keys. One pair for the client and one pair for the server(or other client). They exchange their public keys and encrypt the messages with them. This means:

  1. Client encrypt text with Server public key and send it to server
  2. Server receive encrypted text and decrypt it with his private key
  3. Server generate an answer and encrypt it with Client public key and send it to client
  4. Client receive the answer decrypt it with his private key.

Thank you very much.

bxcrs commented 5 years ago

return false ,maybe check your code: var Base64 = xxxx; Don't use 'var Base64'

OutUniverse commented 5 years ago

It is not very good idea to use the private key in the browser. From the private key it is very easy to generate the public key and therefore there will be no point from the encryption . Also keep in mind that you dont even need the public key , because when you have the private key you can encrypt and decrypt with it .

Is there a good way to solve this problem, such as providing a public key decryption method? Because, as you said, then I will not be able to use RSA, if so, my interactive data will become public, obviously not what I want. Therefore, if we can provide a JS public key decryption, I think it is better, JAVA language can be public key decryption, I think, JS language can also do it. I've seen a framework provided by Google, named JSRSASIGN, which can decrypt through public key. However, it seems to conflict with JAVA. I can't parse the encrypted text with JAVA. Maybe its API is too powerful. I haven't found the right way. I prefer JSEncrypt because it's lightweight and interacts with JAVA. The only disadvantage is that public key decryption is not possible. If it can be provided, it would be very good.

First i want to say that sign/verify is the opposite process of crypt/decrypt. In signing you first use the math formula for decrypting with the private key and after that you use the public key to encrypt the result and get the plain text. So mathematically is possible but i don`t know if some does this.

The whole idea in RSA is to have two pairs of Keys. One pair for the client and one pair for the server(or other client). They exchange their public keys and encrypt the messages with them. This means:

  1. Client encrypt text with Server public key and send it to server
  2. Server receive encrypted text and decrypt it with his private key
  3. Server generate an answer and encrypt it with Client public key and send it to client
  4. Client receive the answer decrypt it with his private key.

But in this way, the client has the private key, all the people can use the private key to get the public key, so does it make sense to use two pairs of Keys?

savs90 commented 5 years ago

It is not very good idea to use the private key in the browser. From the private key it is very easy to generate the public key and therefore there will be no point from the encryption . Also keep in mind that you dont even need the public key , because when you have the private key you can encrypt and decrypt with it .

Is there a good way to solve this problem, such as providing a public key decryption method? Because, as you said, then I will not be able to use RSA, if so, my interactive data will become public, obviously not what I want. Therefore, if we can provide a JS public key decryption, I think it is better, JAVA language can be public key decryption, I think, JS language can also do it. I've seen a framework provided by Google, named JSRSASIGN, which can decrypt through public key. However, it seems to conflict with JAVA. I can't parse the encrypted text with JAVA. Maybe its API is too powerful. I haven't found the right way. I prefer JSEncrypt because it's lightweight and interacts with JAVA. The only disadvantage is that public key decryption is not possible. If it can be provided, it would be very good.

First i want to say that sign/verify is the opposite process of crypt/decrypt. In signing you first use the math formula for decrypting with the private key and after that you use the public key to encrypt the result and get the plain text. So mathematically is possible but i don`t know if some does this. The whole idea in RSA is to have two pairs of Keys. One pair for the client and one pair for the server(or other client). They exchange their public keys and encrypt the messages with them. This means:

  1. Client encrypt text with Server public key and send it to server
  2. Server receive encrypted text and decrypt it with his private key
  3. Server generate an answer and encrypt it with Client public key and send it to client
  4. Client receive the answer decrypt it with his private key.

But in this way, the client has the private key, all the people can use the private key to get the public key, so does it make sense to use two pairs of Keys?

The client has his own private key that no one else has. The server also has his own private key that no one else has.

So you never share private key, but only your public key.

OutUniverse commented 5 years ago

Thank you reply at first. But i want to know where to save the private and public key in the client? In theory, data that exists on the client side is available, so everyone can get it. For example, in browser, if i save the public and private key in the cookie, csrf can get it, and they can use the public key to encrypt and use the private key to decrypt. The problem still bothers me.

savs90 commented 5 years ago

If you dont want to sign and verify who the client is, you can just generate a different key pair for every session. Also if the client is password protected you can just encrypt the private key with the user password and save it in the cookies. In this way the cookie information is useless if you dont have the password.

OutUniverse commented 5 years ago

Thank you very much for your reply. Have a nice day!

abhijithvijayan commented 5 years ago

If you dont want to sign and verify who the client is, you can just generate a different key pair for every session. Also if the client is password protected you can just encrypt the private key with the user password and save it in the cookies. In this way the cookie information is useless if you dont have the password.

How can I encrypt the private key with a password within the browser?

clauderobi commented 4 years ago

openSSL does have this function: RSA_public_decrypt, so I get it is perfectly Ok to decrypt using the public key. It is a pity not be able to do it here with JSEncrypt.

savs90 commented 4 years ago

Encrypting using the public key and decrypting with the private key is one of the most common things people do with asymmetric algorithms, it allows anybody to send you something securely.

If you do it the other way: encrypt using the private key, and decrypt with the public key then it proves the message was sent by the holder of the private key. But because anyone presumably can get hold of the public key, people don't tend to encrypt the whole message, they instead just sign a hash of the data using the private key. Hence RSACryptoServiceProvider has Sign and Verify methods to do just that.

Still, there are Encrypt/Decrypt methods.

puregardenia commented 3 months ago

我们的场景是这样的:Web服务,客户端是浏览器,用于低级别的加密,只是避免个别字段的明文传输。使用固定的RSA密码对,公钥保存在浏览器的js中,服务端使用密钥加密,浏览器端使用公钥解密。

目前的解决方案:重写RSAKey.prototype.decrypt方法,修改doPrivate 为 doPublic,并修改pkcs1unpad2方法,去掉第二个参数和相关的处理逻辑,可以解决公钥无法解密的问题。

使用密钥加密和使用私钥解密是人们使用非廉价算法最常见的操作之一,它允许任何人安全地向您发送内容。

如果您以另一种方式执行此操作:使用私钥加密,加入公钥解密,则证明该消息是由私钥持有者发送的。没有人可以获取公钥,因此人们不会倾向于加密整个消息,而是只是使用私钥对数据的哈希值进行签名。因此,RSACryptoServiceProvider 有 Sign 和 verify 机构名称。

听起来,还是有加密/解密方法。