首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python到Java加密(RSA)

Python到Java加密(RSA)
EN

Stack Overflow用户
提问于 2017-04-27 17:51:48
回答 2查看 5.3K关注 0票数 1

我对python进行加密,并尝试在Java上解密,但总是得到解密错误。

我有一部分用RSA编码的JAVA加密和解密消息代码,用于解密:

代码语言:javascript
复制
import java.security.*;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;

public class Decrypter
{
    public static void main(String[] args)
    {

        try {
            String encoded_data = "PueF1RC5giqmUK9U+X80SwjAjGmgfcHybjjQvWdqHSlua1rv6xr7o6OMutHBU+NRuyCJ3etTQssYOMGiWPITbEC8xr3WG9H9oRRnvel4fYARvQCqsGmf9vO9rXcaczuRKc2zy6jbutt59pKoVKNrbonIBiGN1fx+SaStBPe9Jx+aZE2hymDsa+xdmBSCyjF30R2Ljdt6LrFOiJKaDiYeF/gaej1b7D8G6p0/HBPxiHMWZhx1ZfylSvZ6+zyP0w+MJn55txR2Cln99crGtcdGeBDyBtpm3HV+u0VlW7RhgW5b+DQwjQ/liO+Ib0/ZIPP9M+3sipIwn2DKbC45o0FZHQ==";
            byte[] decodeData = Base64.getDecoder().decode(encoded_data);

            String publicKeyString = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzN2+mrQRXKshq3k0r06" +
                    "0/FoWafOCl6fCCyuu/7SejNU95SN2LZyopA3ipamY5MeK1G1XHOhEfkPWcYcgUbz" +
                    "TdD166nqJGi/O+rNK9VYgfhhqD+58BCmLlNidYpV2iDmUZ9B/cvVsQi96GY5XOaK" +
                    "xuVZfwrDK00xcOq+aCojQEvMh+gry05uvzfSv9xK3ki5/iCMY62ReWlmrY0B19CQ" +
                    "47FuulmJmrxi0rv2jpKdVsMq1TrOsWDGvDgZ8ieOphOrqZjK0gvN3ktsv63kc/kP" +
                    "ak78lD9opNmnVKY7zMN1SdnZmloEOcDB+/W2d56+PbfeUhAHBNjgGq2QEatmdQx3" +
                    "VwIDAQAB";
            KeyFactory kf = KeyFactory.getInstance("RSA");
            byte[] encodedPb = Base64.getDecoder().decode(publicKeyString);
            X509EncodedKeySpec keySpecPb = new X509EncodedKeySpec(encodedPb);
            PublicKey pubKey = kf.generatePublic(keySpecPb);


            Cipher cipherDecr = Cipher.getInstance("RSA");
            cipherDecr.init(Cipher.DECRYPT_MODE, pubKey);
            byte[] cipherDataDecr = cipherDecr.doFinal(decodeData);
            String result = new String(cipherDataDecr);
            System.out.println("result = "+result);
        }catch (Exception e){
            e.printStackTrace(System.out);
        }

    }
}

不幸的是,我无法在这段代码中进行更改,所以我所能做的就是对python部分进行更改。这部分工作正常。为了检查,我使用此代码进行加密:

代码语言:javascript
复制
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;

public class Encrypter
{
    public static void main(String[] args)
    {
        try {   
            String data = "111111111222";
            String privateKeyString = "here is my privat key";

            byte [] encoded = Base64.getDecoder().decode(privateKeyString);
            System.out.println("encoded = "+encoded);

            java.security.Security.addProvider( new org.bouncycastle.jce.provider.BouncyCastleProvider());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            KeySpec ks = new PKCS8EncodedKeySpec(encoded);
            RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(ks);
            System.out.println("privKey = "+privKey);

            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, privKey);

            byte[] cipherData = cipher.doFinal(data.getBytes());

            String card = Base64.getEncoder().encodeToString(cipherData);
            System.out.println("data = "+card);
        }catch (Exception e){
            e.printStackTrace(System.out);
        }

    }
}

当我使用Java代码的结果进行加密并将这个结果用于解密Java文件时,所有的工作都是很棒的。我需要同样的加密部分,但是用python编写。

用python加密的部分

代码语言:javascript
复制
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5

data = '111111111222'
privat_key = 'here is my privat key'
key = RSA.importKey(privat_key)
cipher = PKCS1_v1_5.new(key)
encrypted_message = str(base64.b64encode(cipher.encrypt(base64.b64decode(data))), 'utf8')
print(encrypted_message)

那么,问题是我应该如何加密消息,以便在Java上正确解密?我尝试了不同的lib(标准rsa,Pycrypto,PKCS1_OAEP,PKCS1_v1_5),但没有任何东西帮助我。

我知道使用密钥对的方法是错误的,但这是外部系统的要求。

更新:

使用新实例将我带到某个结果。我改变了格式,正如Maarten Bodewes所说

密码cipherDecr = Cipher.getInstance("RSA/ECB/NoPadding");

解密结果:����2����ٰoܬ���(�RM@�/���u*�d�{���w�b+���v�ݏ[�$�#��xJo�s��F1���X��}���1 ���������t%`�YA/��?��ɼej�X�T�+6Y4D��!���

我看不懂,但也不例外,很好。试着往这边走

更新:

我定义Java使用RSA/ECB/PKCS1Padd作为默认值。所以我应该在python中使用相同的

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-28 15:39:00

首先,我定义了java

代码语言:javascript
复制
Cipher cipher = Cipher.getInstance("RSA");

扩大到

代码语言:javascript
复制
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");

代码语言:javascript
复制
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1PADDING");

对于RSA来说,第二个论点(无或欧洲央行)的定义没有什么不同。RSA不使用它。

所以我需要在python中的加密中添加填充。不幸的是,PyCrypto没有PKCS1PADDING,所以我不能用这个填充加密。

下一步,我找到了M2Crypto lib https://gitlab.com/m2crypto/m2crypto --这个分支适用于python3。只需下载并构建它(回购指令)

比我写的这段代码更有效:

代码语言:javascript
复制
import M2Crypto

# read privat key
privatKey = M2Crypto.RSA.load_key('privat.key')
# encrypt plaintext using privat key
ciphertext = privatKey.private_encrypt(data.encode('utf-8'), M2Crypto.RSA.pkcs1_padding)

encrypted_message = str(base64.b64encode(ciphertext), 'utf8')
print(encrypted_message)

就这样。它对我有用,我相信,它可以帮助你。

票数 4
EN

Stack Overflow用户

发布于 2017-04-27 20:45:55

根据我的代码,B儿GY使用填充来生成签名,所以我认为这是不同的。您可以执行“原始”解密(模幂),并自行移除填充。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43664751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档