日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python能解密java的_实现Java加密,Python解密的RSA非对称加密算法功能

發布時間:2025/4/5 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python能解密java的_实现Java加密,Python解密的RSA非对称加密算法功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

摘要

因為最近業務需要使用到openssl的rsa非對稱加密算法,研究了下它的使用方式,但是特殊在于前端分IOS和android兩端,所以前端部門要求使用java給他們做一個加密工具包,但是因為服務端是python做的,所以需要兩端的數據能夠共通。研究了幾天終于搞定了,下面是一些重要的代碼以及一些我踩過的坑,分享一下。

歡迎訪問我的Github

OpenSSL官網

一. 編譯

make

Perl 5

an ANSI C compiler

a development environment in form of development libraries and C

header files

a supported Unix operating system

二. 安裝

$ ./config

$ make

$ make test

$ make install

三. 生成密鑰

生成的密鑰的路徑是你當前執行命令的路徑

這里默認生成1024長度密鑰

公鑰是基于私鑰來生成的,所以必須先生成私鑰

# 進入openssl

root@VM-0-15-ubuntu:/home/ubuntu# openssl

# 生成一個1024位的私鑰文件rsa_private_key.pem

OpenSSL> genrsa -out rsa_private_key.pem 1024

# 從私鑰中提取公鑰rsa_public_key.pem

OpenSSL> rsa -in rsa_private_key.pem -out rsa_public_key.pem -outform PEM -pubout

# 將私鑰轉換成 DER 格式

OpenSSL> rsa -in rsa_private_key.pem -out rsa_private_key.der -outform der

# 將公鑰轉換成 DER 格式

OpenSSL> rsa -in rsa_public_key.pem -out rsa_public_key.der -pubin -outform der

# 把RSA私鑰轉換成PKCS8格式

OpenSSL> pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt

# 從私鑰創建公鑰證書請求

OpenSSL> req -new -key rsa_private_key.pem -out rsa_public_key.csr

# 生成證書并簽名(有效期10年)

OpenSSL> x509 -req -days 3650 -in rsa_public_key.csr -signkey rsa_private_key.pem -out rsa_public_key.crt

# 把crt證書轉換為der格式

OpenSSL> x509 -outform der -in rsa_public_key.crt -out rsa_public_key.der

# 把crt證書生成私鑰p12文件

OpenSSL> pkcs12 -export -out rsa_private_key.p12 -inkey rsa_private_key.pem -in rsa_public_key.crt

1.JAVA端加密

其實單一語言的加解密都還是比較簡單的,關鍵在于跨語言的兼容問題上。

而且需要特別注意的是我使用的RSA長度是1024的,也就是說我單個需要加密的數據的長度不能超過 1024/8-11=117,實際測試單條數據最大長度是 116 bytes。

如果需要擴大需要加密的單條數據的長度,只需要在生成公鑰的時候設置對應的長度即可。((數據長度+12)*8=密鑰長度)

其中RSA_ALGORITHM 設置的是算法的使用模式,因為Python端使用的是OAEP所以這里用的是RSA/ECB/OAEPWithSHA-256AndMGF1Padding

在Java端我們使用的公鑰格式是DER,如果使用PEM則會出現異常

package site.cnkj.util;

import org.apache.commons.io.FileUtils;

import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;

import javax.crypto.spec.OAEPParameterSpec;

import javax.crypto.spec.PSource;

import java.io.*;

import java.nio.charset.Charset;

import java.nio.file.Files;

import java.nio.file.Path;

import java.nio.file.Paths;

import java.security.*;

import java.security.interfaces.RSAPublicKey;

import java.security.spec.InvalidKeySpecException;

import java.security.spec.MGF1ParameterSpec;

import java.security.spec.X509EncodedKeySpec;

import java.util.ArrayList;

import java.util.Base64;

import java.util.List;

/*

* @version 1.0 created by Carol on 2019/4/15 15:31

*/

public class FileEncryptDecrypt {

private static final String RSA_ALGORITHM = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";

private static final Charset UTF8 = Charset.forName("UTF-8");

static {

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

}

/**

* 加密文件

* @param keyPath 公鑰路徑,DER

* @param input 輸入文件地址

* @param output 輸出文件地址

*/

public static boolean encrypt(String keyPath, String input, String output){

FileInputStream fileInputStream = null;

FileOutputStream fileOutputStream = null;

List list = new ArrayList();

try {

byte[] buffer = Files.readAllBytes(Paths.get(keyPath));

X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

PublicKey publicKey = keyFactory.generatePublic(keySpec);

File inputFile = new File(input);

File outputFile = new File(output);

fileInputStream = new FileInputStream(inputFile);

fileOutputStream = new FileOutputStream(outputFile);

byte[] inputByte = new byte[116];

int len;

while((len = fileInputStream.read(inputByte)) != -1){

list.add(new String(inputByte, 0, len));

}

for (String s : list) {

byte [] encrypted = encrypt(publicKey, s);

fileOutputStream.write(encrypted);

fileOutputStream.flush();

}

fileOutputStream.close();

fileInputStream.close();

return true;

} catch (Exception e) {

e.printStackTrace();

}

return false;

}

private static byte[] encrypt(PublicKey publicKey, String message) throws Exception {

Cipher cipher = Cipher.getInstance(RSA_ALGORITHM,"BC");

cipher.init(Cipher.ENCRYPT_MODE, publicKey, new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));

cipher.init(Cipher.ENCRYPT_MODE, publicKey);

return Base64.getEncoder().encode(cipher.doFinal(message.getBytes(UTF8)));

}

/**

* 從字符串中加載公鑰

*

*/

private static RSAPublicKey loadPublicKey(String publicKeyStr) throws Exception {

try {

byte[] buffer = new BASE64Decoder().decodeBuffer(publicKeyStr);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);

return (RSAPublicKey) keyFactory.generatePublic(keySpec);

} catch (NoSuchAlgorithmException e) {

throw new RuntimeException(e);

} catch (InvalidKeySpecException e) {

throw new RuntimeException(e);

}

}

public static void main(String [] args) throws Exception {

encrypt("F:\\dls\\chunk\\config\\rsa_public_key.der", "C:\\Users\\Carol\\Desktop\\file\\868663032830438_migu$user$login$_1554947856915.log","F:\\868663032830438_migu$user$login$_1554947856915.log");

}

}

2.Python端解密

Python端可以使用的模塊是很多的,通常可以用rsa、Crypto、PyCryptodome、PyCrypt等,需要注意的是其中PyCrypt已經停止維護了不建議使用,但是幸運的是PyCrypt有一個分支叫PyCryptodome

為了便于閱讀,Java端對加密后的數據進行了Base64的格式轉換,因此在Python端也同樣需要對獲取的加密后的數據進行Base64的轉換后再進行解密。

通過觀察,發現加密后進行Base64轉換后的數據結束符為“==”,因此我在這里是直接根據結束符進行拆分數據的,拆分后的數據分別解密后放在同一個字符串集合里面,這里你不需要但是如果出現換行的情況是否還需要自己手動設置換行,當解密后原有的換行符依然可用。

但是需要注意的是在windows環境下文件的換行符是"\r\n",加密后依然加密的是"\r\n",但是,但我們解密后寫入文件的時候應當替換"\r\n"為"\n",否則你會發現多了一行換行,因為當Python重寫寫入文件的時候認為"\r\n"為“回車換行”,所以體現在文件中就是兩次換行的效果了。

在 _init()方法中獲取私鑰的位置只需要把os.path.join(os.path.dirname(os.getcwd()), "config", "rsa_private_key.pem")替換成你自己的私鑰路徑即可

在Python端我們使用的私鑰格式是PEM

#!/usr/bin/env python

# -*- coding: utf-8 -*-

"""

@Time : 2019/4/12

@Author : Carol

@Site :

@File : FileDecryptEncrypt.py

@Software: PyCharm

@Description:

"""

from Crypto.Random import get_random_bytes

from Crypto.Cipher import AES

from Crypto.Cipher import PKCS1_OAEP

from Crypto.PublicKey import RSA

from Crypto.Hash import SHA256

import base64

import traceback

import os

class FileDecryptEncrypt():

def __init__(self):

try:

self.private_key = RSA.import_key(open(os.path.join(os.path.dirname(os.getcwd()), "config", "rsa_private_key.pem")).read())

except Exception as e:

traceback.print_exc()

print("加載密鑰出現異常")

def decrypt(self, root_path, res_path):

"""

RSA的文件解密

:param root_path: 加密后的文件

:param res_path: 解密后的文件

:return: 解密結果

"""

new_line = b""

cipher = PKCS1_OAEP.new(self.private_key, hashAlgo=SHA256)

try:

with open(root_path, "r") as rootf:

lines = rootf.read().split("==")

for line in lines:

if len(line) > 0:

line = line + "=="

b64_decoded_message = base64.b64decode(line)

cipherContent = cipher.decrypt(b64_decoded_message)

new_line = new_line + cipherContent

if not os.path.exists(os.path.dirname(res_path)):

os.makedirs(os.path.dirname(res_path))

with open(res_path, "w") as resf:

resf.write(str(new_line, encoding="UTF-8").replace("\r\n", "\n"))

return True

except Exception as e:

traceback.print_exc()

return False

if __name__ == '__main__':

FileDecryptEncrypt().decrypt("F:\\868663032830438_1554947856915.log","D:\\\\868663032830438_1554947856915.log")

總結

以上是生活随笔為你收集整理的python能解密java的_实现Java加密,Python解密的RSA非对称加密算法功能的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。