delphi7aes加密解密与java互转_跨语言(java vs python vs nodejs)的RSA加解密问题探讨
多次被問到這樣的問題:
java服務(wù)端的rsa加密操作已經(jīng)完成,返回一個(gè)16進(jìn)制的字符串給python平臺(tái),但是在python進(jìn)行私鑰解密的時(shí)候發(fā)現(xiàn)行不通。。。。
前端python加密,后端用java解密,解不出來
還有諸如nodejs
從理論上來說,rsa加密的基礎(chǔ)都是一樣的,不存在一個(gè)語(yǔ)言加密,另一個(gè)語(yǔ)言解密不出來的情況。那出問題的只能是我們使用的方法不對(duì)。
java vs python
聲明:java的加密解密模塊需要更加精細(xì)的算法細(xì)節(jié)指定
java的加密方式
javax.crypto.Cipher,定義的獲取方式
static Cipher getInstance(String transformation)Returns a Cipher object that implements the specified transformation.static Cipher getInstance(String transformation, Provider provider)Returns a Cipher object that implements the specified transformation.static Cipher getInstance(String transformation, String provider)Returns a Cipher object that implements the specified transformation.有兩個(gè)重要參數(shù):
1. transformation定義為
A transformation is a string that describes the operation (or set of operations) to be performed on the given input, to produce some output. A transformation always includes the name of a cryptographic algorithm (e.g., AES), and may be followed by a feedback mode and padding scheme.A transformation is of the form:"algorithm/mode/padding" or"algorithm"(in the latter case, provider-specific default values for the mode and padding scheme are used). For example, the following is a valid transformation: Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");transformation有以下幾種:
Every implementation of the Java platform is required to support the following standard Cipher transformations with the keysizes in parentheses:AES/CBC/NoPadding (128)AES/CBC/PKCS5Padding (128)AES/ECB/NoPadding (128)AES/ECB/PKCS5Padding (128)DES/CBC/NoPadding (56)DES/CBC/PKCS5Padding (56)DES/ECB/NoPadding (56)DES/ECB/PKCS5Padding (56)DESede/CBC/NoPadding (168)DESede/CBC/PKCS5Padding (168)DESede/ECB/NoPadding (168)DESede/ECB/PKCS5Padding (168)RSA/ECB/PKCS1Padding (1024, 2048)RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)These transformations are described in the Cipher section of the Java Cryptography Architecture Standard Algorithm Name Documentation. Consult the release documentation for your implementation to see if any other transformations are supported.2.provider
可以通過Security.getProviders()查看
java.security.Provider [] providers=Security.getProviders(); for(int i=0;i具體的provider如下:
SUNSunRsaSignSunECSunJSSESunJCESunJGSSSunSASLXMLDSigSunPCSCSunMSCAPIpython的加密方式需要到具體的代碼里面了,如
from crypto.PublicKey import RSAfrom crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5# from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5def rsaEncrypt(message): key = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYLCumWz6MGHmAMLIaPt3SItIhMYHuyLn48muQz2xKj9PVqETGfjq/GTxHE3wfvGCEs/JXY1rV4uysUuAS/xwZuyJ9j+sB599lzmpxdhIWu/jGMR0h86nnpNUcssYwR3Bww3oU5+dYEtGpfOytMyh3eJeUZiNNBXqH+IaSYfU3hwIDAQAB' key1=base64.b64decode(key) rsaKey=RSA.importKey(key1) cipher=Cipher_pkcs1_v1_5.new(rsaKey) temp=cipher.encrypt(message) return binascii.b2a_hex(temp)if __name__ == '__main__': rsaEncrypt(13950346593)進(jìn)入encypt方法中:
def encrypt(self, message): """Produce the PKCS#1 v1.5 encryption of a message. This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and it is specified in `section 7.2.1 of RFC8017 `_. :param message: The message to encrypt, also known as plaintext. It can be of variable length, but not longer than the RSA modulus (in bytes) minus 11. :type message: bytes/bytearray/memoryview :Returns: A byte string, the ciphertext in which the message is encrypted. It is as long as the RSA modulus (in bytes). :Raises ValueError: If the RSA key length is not sufficiently long to deal with the given message. """發(fā)現(xiàn)其支持的是
PKCS#1 v1.5 encryption對(duì)應(yīng)java的模式是:
RSA/ECB/PKCS1Padding (1024, 2048)IvParameterSpec
This class specifies an initialization vector (IV). Examples which use IVs are ciphers in feedback mode, e.g., DES in CBC mode and RSA ciphers with OAEP encoding operation.
java和nodejs
用NODE RSA JS 加密解密正常,用JAVA RSAUtils工具類加密解密正常。但是用node加密玩的java解密不了。原因:node默認(rèn)的是
DEFAULT_ENCRYPTION_SCHEME = 'pkcs1_oaep' 而java中默認(rèn)的是pkcs1。
node-rsa源碼:https://github.com/rzcoder/node-rsa/blob/ea5c17d9351c857c0594d7921c596ff5636882f1/src/NodeRSA.js
var DEFAULT_ENCRYPTION_SCHEME = 'pkcs1_oaep';
node-rsa官方文檔:https://www.npmjs.com/package/node-rsa
Options
You can specify some options by second/third constructor argument, or over key.setOptions()method.
environment — working environment (default autodetect):'browser' — will run pure js implementation of RSA algorithms.'node' for nodejs >= 0.10.x or io.js >= 1.x — provide some native methods like sign/verify and encrypt/decrypt.encryptionScheme — padding scheme for encrypt/decrypt. Can be 'pkcs1_oaep' or 'pkcs1'. Default 'pkcs1_oaep'.signingScheme — scheme used for signing and verifying. Can be 'pkcs1' or 'pss' or 'scheme-hash' format string (eg 'pss-sha1'). Default 'pkcs1-sha256', or, if chosen pss: 'pss-sha1'.Notice: This lib supporting next hash algorithms: 'md5', 'ripemd160', 'sha1', 'sha256', 'sha512' in browser and node environment and additional 'md4', 'sha', 'sha224', 'sha384' in node only.
所以要保持一致:
import NodeRSA from 'node-rsa';const rsa_encrypt = (data) => { let key = new NodeRSA('-----BEGIN PUBLIC KEY-----' + 'MIGfMA0。。。。。。。AQAB' + '-----END PUBLIC KEY-----'); // key.generateKeyPair(1024); key.setOptions({encryptionScheme: 'pkcs1'}) let encryptKey = key.encrypt(data, 'base64') return encryptKey;}后臺(tái):
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 對(duì)數(shù)據(jù)分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; }參考文獻(xiàn):
【1】https://docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html#getInstance(java.lang.String)
【2】https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#Cipher
【3】https://docs.oracle.com/javase/7/docs/api/javax/crypto/spec/IvParameterSpec.html
【4】https://blog.csdn.net/mshootingstar/article/details/56496719
總結(jié)
以上是生活随笔為你收集整理的delphi7aes加密解密与java互转_跨语言(java vs python vs nodejs)的RSA加解密问题探讨的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux怎么启动打印服务,Linux打
- 下一篇: 集成学习之参数调整策略