本文目錄一覽:
- 1、java生成的rsa公鑰 能在python上使用嗎
- 2、密碼學基礎之對稱加密(一)
- 3、python語言可以加密嗎
- 4、python中AES 用ECB模式加密之後為什麼和C#加密之後的結果不一樣
- 5、怎麼樣給python文件加密
- 6、Python進行 AES CBC-128bit PKCS7/PKCS5 填充加密解密
java生成的rsa公鑰 能在python上使用嗎
肯定可以,這個跟語言是無關的
Python上RSA加密的庫挺多的,最開始使用的是rsa,因為比較簡單嘛!測試的時候也是用 python模擬App的訪問,順利通過!
然而App開發者反饋,python測試腳本沒法移植到java上,因為java的加密解密模塊需要更加精細的演算法細節指定,否則java加密過的數據python是解不出來的。
當初就是因為rsa模塊簡單,不需要注重細節才選的,自己又不是專業搞加密解密的。沒辦法了,只能硬著頭皮,捋了一遍RSA的加密原理。網上還是有比較多的講述比較好的文章,比如RSA演算法原理
原理是懂了,但具體到python和java的區別上,還是一頭霧水。最終python的RSA模塊換成Crypto,因為支持的參數比較多。搜了很多網站講的都不是很詳細,stackflow上有幾篇還可以,借鑒了一下,最後測試通過了。還是直接上代碼吧。
Java代碼
//下面這行指定了RSA演算法的細節,必須更python對應
private static String RSA_CONFIGURATION = “RSA/ECB/OAEPWithSHA-256AndMGF1Padding”;
//這個貌似需要安裝指定的provider模塊,這裡沒有使用
private static String RSA_PROVIDER = “BC”;
//解密 Key:私鑰
public static String decrypt(Key key, String encryptedString){
try {
Cipher c = Cipher.getInstance(RSA_CONFIGURATION);
c.init(Cipher.DECRYPT_MODE, key, new OAEPParameterSpec(“SHA-256”, “MGF1”, MGF1ParameterSpec.SHA256,
PSource.PSpecified.DEFAULT));
byte[] decodedBytes;
decodedBytes = c.doFinal(Base64.decode(encryptedString.getBytes(“UTF-8”)));
return new String(decodedBytes, “UTF-8”);
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Base64DecodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
//加密 Key一般是公鑰
public static String encrypt(Key key, String toBeEncryptedString){
try {
Cipher c = Cipher.getInstance(RSA_CONFIGURATION);
c.init(Cipher.ENCRYPT_MODE, key, new OAEPParameterSpec(“SHA-256”, “MGF1”, MGF1ParameterSpec.SHA256,
PSource.PSpecified.DEFAULT));
byte[] encodedBytes;
encodedBytes = c.doFinal(toBeEncryptedString.getBytes(“UTF-8”));
return Base64.encode(encodedBytes);
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
//通過Pem格式的字元串(PKCS8)生成私鑰,base64是去掉頭和尾的b64編碼的字元串
//Pem格式私鑰一般有2種規範:PKCS8和PKCS1.注意java在生成私鑰時的不同
static PrivateKey generatePrivateKeyFromPKCS8(String base64)
{
byte[] privateKeyBytes;
try {
privateKeyBytes = Base64.decode(base64.getBytes(“UTF-8”));
KeyFactory kf = KeyFactory.getInstance(“RSA”);
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = kf.generatePrivate(ks);
return privateKey;
} catch (Base64DecodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
//通過Pem格式的字元串(PKCS1)生成私鑰,base64是去掉頭和尾的b64編碼的字元串
static PrivateKey generatePrivateKeyFromPKCS1(String base64)
{
byte[] privateKeyBytes;
try {
privateKeyBytes = Base64.decode(base64.getBytes(“UTF-8”));
KeyFactory kf = KeyFactory.getInstance(“RSA”);
X509EncodedKeySpec ks = new X509EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = kf.generatePrivate(ks);
return privateKey;
} catch (Base64DecodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
//通過Pem格式的字元串(PKCS1)生成公鑰,base64是去掉頭和尾的b64編碼的字元串
//Pem格式公鑰一般採用PKCS1格式
static PublicKey generatePublicKeyFromPKCS1(String base64)
{
byte[] publicKeyBytes;
try {
publicKeyBytes = Base64.decode(base64.getBytes(“UTF-8”));
KeyFactory kf = KeyFactory.getInstance(“RSA”);
X509EncodedKeySpec ks = new X509EncodedKeySpec(publicKeyBytes);
PublicKey publicKey = kf.generatePublic(ks);
return publicKey;
} catch (Base64DecodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
//通過modulus和exponent生成公鑰
//參數含義就是RSA演算法里的意思
public static RSAPublicKey getPublicKey(String modulus, String exponent) {
try {
BigInteger b1 = new BigInteger(modulus);
BigInteger b2 = new BigInteger(exponent);
KeyFactory keyFactory = KeyFactory.getInstance(“RSA”);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
Python 代碼
from Config import config
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
key = RSA.generate(1024)
pubkey = key.publickey().key
def Decrypt(prikey,data):
try:
cipher = PKCS1_OAEP.new(prikey, hashAlgo=SHA256)
return cipher.decrypt(data)
except:
traceback.print_exc()
return None
def Encrypt(pubkey,data):
try:
cipher = PKCS1_OAEP.new(pubkey, hashAlgo=SHA256)
return cipher.encrypt(data)
except:
traceback.print_exc()
return None
1234567891011121314151617181920212223
總結
主要是對RSA演算法不是很熟悉,其中很多術語不懂,導致跟java里的加密模塊的函數和類對應不上。
RSA演算法的細節到現在也是一知半解,但真的沒時間去深入學習了。
密碼學基礎之對稱加密(一)
就不給定義了,我簡單解釋下,就是我的信息不想讓別人知道,使用 秘鑰(key) 對我的信息進行 加密(encrypt) ,變成鬼符一樣的 秘文(ciphertext) 。別人就算看到了,也無法識別,只有有了秘鑰,把秘文 解密(decrypt) 後才能看懂信息,秘鑰呢?一般人我不告訴他。我的秘鑰是私密信息,所以也叫 私鑰(private key) ,加密和解密用的秘鑰是相同的,所以叫 「對稱加密」 ,也叫 「私鑰加密」 。
對於明文plaintext,和對稱秘鑰key
加密過程 E(plaintext, key) = ciphertext
解密過程 D(ciphertext, key) = plaintext
對稱加密的分為 分組密碼(block cipher) 和 流密碼(stream cipher) 兩種類型。本文只介紹分組密碼。
分組密碼是每次只能處理特定長度的一塊(block)數據的一類加解密演算法。AES就是一種分組密碼演算法。AES加密演算法每次可以加密的塊長度是128位(bit)。
ECB模式
使用AES加密演算法ECB模式,每次能加密128位數據,即16個位元組。如果要加密48個位元組內容,我們需要把數據分為3組,每組16個位元組,分別為P1、P2、P3。P1、P2、P3加密後形成的秘文分別為C1、C2、C3,我們把C1、C2、C3依次拼接起來就成為最終的加密結果。
CBC模式
《對稱加密之對稱加密二》正在寫作,會包含分組密碼的更多模式,流密碼及AES的更多知識。
DES加密:舊的加密演算法,NIST規定僅能用於遺留系統和TDEA。(參考文獻[CNS] 3.2章)
TDEA(Triple DEA)加密:很多資料也叫3DES(Triple DES)。(參考文獻[SP800-67])
Python 可以使用 pycrypto 模塊進行AES加解密。安裝 pycrypto 可使用命令 pip install pycrypto 安裝。
下面AES演示第一版,先看下,緊接著就會升級到第二版本。
運行一下,能正常加解密。但是,如果你把要加密的文本,從 aesAlgorithmDemo 改為 hello ,就會運行報錯:
這是因為,AES的分組長度是128位,即16個位元組。有些AES實現,要加密的消息長度不是16個位元組的倍數需要填充。
填充的方法一般是按照PKCS#7填充標準。
如果要數據的長度不是分組的整數倍,需要填充數據到分組的倍數,如果數據的長度是分組的倍數,需要填充分組長度的數據,填充的每個位元組值為填充的長度。PKCS#7支持的分組長度為1到255個位元組。
舉一些例子:
AES的分組長度為16個位元組,不管秘鑰是128位、192位還是256位。如果要加密的數據長度是5個位元組,你需要填充11個位元組,填充的內容位填充的長度0x0b。填充後類似下面表示
如果數據長度是30個位元組,需要填充2個位元組,每個位元組的內容為0x02,如果數據成都恰好為16的倍數,需要填充16個位元組,每個位元組的內容為0x10。
弄明白填充的概念後,我們重寫加解密函數如下:
這樣填充後會不會可其它系統不兼容?不會。一般的AES程序都是支持PKCS#7填充的。
密碼學基礎之RSA與不對稱秘鑰
密碼學基礎系列
[CNS] 《密碼編碼學與網路安全》(第六版)
[SP800-67] NIST Special Publication 800-67 Revision 1, Recommendation for Triple Data Encryption Algorithm (TDEA) Block Cipher, January 2012.
[SSH] OpenSSH CBC模式信息泄露漏洞
[NIST SP 800-57 Part 1 Rev. 4] Recommendation for Key Management, Part 1: General
python語言可以加密嗎
我們所說的加密方式都是對二進位編碼的格式進行加密,對應到python中,則是我們的bytes.
所以當我們在Python中進行加密操作的時候,要確保我們的操作是bytes,否則就會報錯.
將字元串和bytes互相轉換可以用encode()和decode()方法,如下所示:
注:兩位十六進位常常用來顯示一個二進位位元組.
推薦學習《python教程》。
python中AES 用ECB模式加密之後為什麼和C#加密之後的結果不一樣
AES是美國國家標準技術研究所NIST旨在取代DES的21世紀的加密標準。 AES的基本要求是,採用對稱分組密碼體制,密鑰長度的最少支持為128、192、256,分組長度128位,演算法應易於各種硬體和軟體實現。1998年NIST開始AES第一輪分析、測試和徵集
怎麼樣給python文件加密
簡單模式:
from hashlib import md5
def md5_file(name):
m = md5()
a_file = open(name, ‘rb’) #需要使用二進位格式讀取文件內容
m.update(a_file.read())
a_file.close()
return m.hexdigest()
if __main__ == ‘__init__’:
print md5_file(‘d:/test.txt’)
大文件速度更快一點的方式
#!/usr/bin/python
#encoding=utf-8
import io
import sys
import hashlib
import string
def printUsage():
print (””’Usage: [python] pymd5sum.py ”’)
def main():
if(sys.argv.__len__()==2):
#print(sys.argv[1])
m = hashlib.md5()
file = io.FileIO(sys.argv[1],’r’)
bytes = file.read(1024)
while(bytes != b”):
m.update(bytes)
bytes = file.read(1024)
file.close()
#md5value = “”
md5value = m.hexdigest()
print(md5value+”\t”+sys.argv[1])
#dest = io.FileIO(sys.argv[1]+”.CHECKSUM.md5″,’w’)
#dest.write(md5value)
#dest.close()
else:
printUsage()
main()
Python進行 AES CBC-128bit PKCS7/PKCS5 填充加密解密
你看一下這個例子吧。可以參考下面的地址:前面加上http,把句號改成點。
likang。me/blog/2013/06/05/python-pycrypto-aes-ecb-pkcs-5/
# -*- coding: utf-8 -*-
from Crypto.Cipher import AES
import os
BS = AES.block_size
pad = lambda s: s + (BS – len(s) % BS) * chr(BS – len(s) % BS)
unpad = lambda s : s[0:-ord(s[-1])]
key = os.urandom(16) # the length can be (16, 24, 32)
text = ‘to be encrypted’
cipher = AES.new(key)
encrypted = cipher.encrypt(pad(text)).encode(‘hex’)
print encrypted # will be something like ‘f456a6b0e54e35f2711a9fa078a76d16’
decrypted = unpad(cipher.decrypt(encrypted.decode(‘hex’)))
print decrypted # will be ‘to be encrypted’
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/243799.html