- 浏览: 146540 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (95)
- java (25)
- 数据库 (9)
- js (0)
- 框架 (10)
- 小问题 (8)
- 转载 (2)
- 配置开发环境 (6)
- 其它 (4)
- 功能记录 (2)
- 安全 (1)
- shell (3)
- spring ibaitis struts2 redis desc (1)
- spring security3.1 (1)
- 小问题 环境 (1)
- 小问题 环境 DelegatingFilterProxy cannot be cast to Filter (0)
- redis filter java (1)
- java redis (2)
- spring quartz 集群 批处理 (1)
- java mybatis (1)
- Junit soap (1)
- mock junit (0)
- mock junit spring (1)
- java jsoup (0)
- jsoup (1)
- python27 pycharm (1)
- maven pom (1)
- java log (1)
- mybatis 分页 (1)
- mysql (1)
- 业务 (1)
- java 测试 (1)
- java zookeeper 批处理 (1)
- hive hadoop (1)
- hive (1)
- hadoop (1)
- maven archetype (1)
- python rsa (1)
- python 页面分析 (1)
- python (0)
最新评论
-
wuyafeng123:
秒杀活动设计思路 -
indiajohns:
非常感谢,很快解决了我的问题
jmesa查询条件中文的编码转换问题 -
yujiaao:
太好了,感谢啊!这行在我这好象不行:URLDecoder.de ...
jmesa查询条件中文的编码转换问题 -
michael_wong:
呵呵,找到啦。在这里有全部源码:http://ishare. ...
Maven权威指南 的simple-parent 工程源码 -
michael_wong:
我也在找啊
Maven权威指南 的simple-parent 工程源码
加密使用的是公钥对数据进行加密,而且当你使用一把1024bit的rsa公钥的时候,你一次只能加密最多117byte的数据,如果数据量超过这个数,可能会涉及到对数据进行分段加密的问题。而且现在rsa 1024bit长度的钥匙已经被证明了不够安全,应该尽量使用2048bit长度的钥匙。2048bit长度的钥匙一次可以加密245byte长度的数据。这个计算方法是 2048bit/8 = 256byte - 11byte = 245byte长数据。就是钥匙长度减去11byte得到的自己最大能一次加密多长的数据。如果超过了就会报错,所以很多平台要求对数据用公钥进行加密,就可能涉及到分段加密的问题。同时要注意的是,解密的时候不存在这11byte的减少。就是说一把1024bit的钥匙可以解密128byte长的数据而2048bit的可以解密256byte的数据。
RSA非对称加密内容长度有限制,1024位key的最多只能加密117位数据,否则就会报错(javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes)
解决办法是用对称加密(AES/DES etc)加密数据,然后用RSA公钥加密对称加密的密钥,用RSA的私钥解密得到对称加密的密钥,然后完成反向操作得到明文。
java版分段加密
长度大于117的分段加密
处理逻辑是,先按117长度切分,切分完成后加密成byte数组,这些byte数组长度都是一样的;然后把这些数组前后串联,转成base64,完成加密。
RSA非对称加密内容长度有限制,1024位key的最多只能加密117位数据,否则就会报错(javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes)
解决办法是用对称加密(AES/DES etc)加密数据,然后用RSA公钥加密对称加密的密钥,用RSA的私钥解密得到对称加密的密钥,然后完成反向操作得到明文。
from Crypto import Random #from Crypto.Hash import SHA from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 #from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5 from Crypto.PublicKey import RSA import base64 #伪随机数生成器 random_generator = Random.new().read # rsa算法生成实例 rsa = RSA.generate(2048, random_generator) # master的秘钥对的生成 private_pem = rsa.exportKey() with open('master-private.pem', 'wb+') as f: f.write(private_pem) public_pem = rsa.publickey().exportKey() with open('master-public.pem', 'wb') as f: f.write(public_pem) # ghost的秘钥对的生成 private_pem = rsa.exportKey() with open('master-private.pem', 'wb') as f: f.write(private_pem) public_pem = rsa.publickey().exportKey() with open('master-public.pem', 'wb') as f: f.write(public_pem) message = 'hello ghost, this is a plian text' cipher_text ='' with open('master-public.pem', 'rb+') as f: key = f.read() rsakey = RSA.importKey(key) cipher = Cipher_pkcs1_v1_5.new(rsakey) cipher_text = base64.b64encode(cipher.encrypt(bytes(message,"utf-8"))) print(cipher_text) text='' with open('master-private.pem', 'rb+') as f: key = f.read() rsakey = RSA.importKey(key) cipher = Cipher_pkcs1_v1_5.new(rsakey) text = str(cipher.decrypt(base64.b64decode(cipher_text), random_generator),"utf-8") print(text) assert text == message, 'decrypt falied'
java版分段加密
import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.MessageDigest; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.crypto.Cipher; private static final String EQUAL_FLAG = "="; private static final String APPEND_FLAG = "&"; /** * 字节数据转字符串专用集合 */ private static final char[] HEX_CHAR= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; /** * 加密算法RSA */ public static final String KEY_ALGORITHM = "RSA"; /** * 签名算法 */ public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** * 获取公钥的key */ private static final String PUBLIC_KEY = "RSAPublicKey"; /** * 获取私钥的key */ private static final String PRIVATE_KEY = "RSAPrivateKey"; /** * RSA加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** * <p> * 生成密钥公钥和私 * </p> * * @return * @throws Exception */ public static Map<String, Object> genKeyPair() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** * <p> * 用私钥对信息生成数字签名 * </p> * * @param data 已加密数�? * @param privateKey 私钥(BASE64编码) * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); return Base64Utils.encode(signature.sign()); } /** * <p> * 校验数字签名 * </p> * * @param data 已加密数�? * @param publicKey 公钥(BASE64编码) * @param sign 数字签名 * * @return * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicK = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicK); signature.update(data); return signature.verify(Base64Utils.decode(sign)); } /** * <P> * 私钥解密 * </p> * * @param encryptedData 已加密数�? * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(String date) throws Exception { byte[] encryptedData = Base64Utils.decode(date.replace(" ", "+")) ; 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 cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解�? 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; } /** * <p> * 公钥解密 * </p> * * @param encryptedData 已加密数�? * @param publicKey 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解�? 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; } /** * 字节数据转十六进制字符串 * @param data 输入数据 * @return 十六进制内容 */ public static String byteArrayToString(byte[] data){ StringBuilder stringBuilder= new StringBuilder(); for (int i=0; i<data.length; i++){ //取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右�? stringBuilder.append(HEX_CHAR[(data[i] & 0xf0)>>> 4]); //取出字节的低四位 作为索引得到相应的十六进制标识符 stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]); /* if (i<data.length-1){ stringBuilder.append(' '); } */ } return stringBuilder.toString(); } /** * <p> * 公钥加密 * </p> * * @param data 源数�? * @param publicKey 公钥(BASE64编码) * @return * @throws Exception */ public static String encryptByPublicKey(byte[] data) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加�? // Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加�? while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); // return encryptedData; return Base64Utils.encode(encryptedData); } /** * <p> * 私钥加密 * </p> * * @param data 源数�? * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, 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.ENCRYPT_MODE, privateK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加�? while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** * <p> * 获取私钥 * </p> * * @param keyMap 密钥�? * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return Base64Utils.encode(key.getEncoded()); } /** * <p> * 获取公钥 * </p> * * @param keyMap 密钥�? * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return Base64Utils.encode(key.getEncoded()); } /** * function:将json格式的字符串转化成键值对&形式,并且按ACSII码从小到大排�? * */ public static String formatSignMsg(Map<String, String> paraMap,boolean urlencode,boolean keyLowerCase) { // System.out.println("1.\n"+paraMap); StringBuffer buff = new StringBuffer(); List<Map.Entry<String, String>> keyList = new ArrayList<Map.Entry<String, String>>(paraMap.entrySet()); Collections.sort(keyList,new Comparator<Map.Entry<String, String>>() { @Override public int compare(Map.Entry<String, String> src,Map.Entry<String, String> tar) { return (src.getKey()).toString().compareTo(tar.getKey()); } }); for (int i = 0; i < keyList.size(); i++) { Map.Entry<String, String> item = keyList.get(i); String key = item.getKey(); String val = item.getValue(); if (key!=null && !"".equals(key)) { if (urlencode) { try { val = URLEncoder.encode(val, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } } buff.append(keyLowerCase?key.toLowerCase():key); buff.append(EQUAL_FLAG); buff.append(val); buff.append(APPEND_FLAG); } } if (buff.length() > 0) { System.out.println("2.\n"+buff.substring(0, buff.length() - 1)); return buff.substring(0, buff.length() - 1); }else return null; } public final static String Sha1(String s) { char hexDigits[]={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; try { byte[] btInput = s.getBytes("UTF-8"); MessageDigest mdInst = MessageDigest.getInstance("sha-1"); mdInst.update(btInput); byte[] md = mdInst.digest(); int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } // System.out.println("aaa:\n"+new String(str)); return new String(str); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 16进制的字符串表示转成字节数组 * * @param hexString * 16进制格式的字符串 * @return 转换后的字节数组 **/ public static byte[] hexStr2ByteArray(String hexString) { if (hexString==null) throw new IllegalArgumentException("this hexString must not be empty"); hexString = hexString.toLowerCase(); final byte[] byteArray = new byte[hexString.length() / 2]; int k = 0; for (int i = 0; i < byteArray.length; i++) { //因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先 //将hex 转换成byte "&" 操作为了防止负数的自动扩展 // hex转换成byte 其实只占用了4位,然后把高位进行右移四位 // 然后“|”操作 低四位 就能得到 两个 16进制数转换成一个byte. // byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff); byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff); byteArray[i] = (byte) (high << 4 | low); k += 2; } return byteArray; } }
长度大于117的分段加密
处理逻辑是,先按117长度切分,切分完成后加密成byte数组,这些byte数组长度都是一样的;然后把这些数组前后串联,转成base64,完成加密。
from pandas import json import base64 import json from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 from Crypto.PublicKey import RSA import requests # app公钥---自己生成 # public_key ="dfafasddfasdfasdfasdfasdfasfasdf" # 前后台公钥---自己生成 public_key = "dfadfasdfasdfaddds" def get_encrypt_data(params): """分段加密""" params = json.dumps (params) params = params.encode ("utf-8") length = len (params) default_length = 117 if length < default_length: return encrypt_data (params) offset = 0 params_lst = [] while length - offset > 0: if length - offset > default_length: params_lst.append (encrypt_data (params[offset:offset + default_length])) else: params_lst.append (encrypt_data (params[offset:length - offset])) offset += default_length n = len(params_lst) c = 1 res = params_lst[0] while c < n: res = res+params_lst[c] c += 1 return res def encrypt_data(params): """使用公钥对数据加密""" key = public_key rsakey = RSA.importKey(base64.b64decode(key)) cipher = Cipher_pkcs1_v1_5.new(rsakey) text = cipher.encrypt(params) return text a="123134124151431234124121111111111111111123134123134124151431234124121111111111111111123134124151431234124121111111111111111123134124151431234124121111111111111111124151431234124121111111111111111123134124151431234124121111111111111111" c = get_encrypt_data(a) c2=base64.b64encode (c).decode('ascii') print(c2)
相关推荐
### Python 实现 AES 和 RSA 加解密方法 #### 一、引言 在现代信息安全领域,数据加密技术扮演着至关重要的角色。其中,对称加密和非对称加密是最为常见的两种加密方式。本篇文章将详细介绍如何使用 Python 来实现 ...
"基于python的RSA算法数字签名生成软件设计与实现" 本文主要讨论了基于Python的RSA算法数字签名生成软件的设计与实现。数字签名技术是当前信息安全领域的一个重要研究方向,通过数字签名技术可以提高信息安全系数,...
本篇文章将详细介绍如何使用Python来生成RSA密钥对,并通过具体的示例代码展示如何实现RSA加密与解密的过程。 #### 二、基础知识回顾 RSA算法基于大整数因子分解难题,由Ron Rivest、Adi Shamir和Leonard Adleman三...
RSA加密工具-可生成秘钥-自定义加密文本
- **快速模幂算法**:该算法用于执行加密和解密操作,即计算`a^b mod n`。 - **扩展欧几里得算法**:此算法用于求解私钥d,即求解方程`de ≡ 1 (mod φ(n))`。 综上所述,通过本实验报告的学习和实践,我们可以深入...
首先,我们需要生成一对公钥和秘钥,然后使用公钥来加密数据,并使用秘钥来解密数据。最后,我们可以使用数字签名来验证数据的完整性和安全性。 结论 数字签名技术是信息安全的重要组成部分,基于 RSA 算法的数字...
将RSA PEM密钥(PKCS#1)转换为与.Net兼容的XML 要求: 经过python 2.7版测试 使用pycrypto 对于Windows,您可以在此处找到二进制文件: : 经测试的方案: PHP使用PEM密钥加密/解密,C#使用隐蔽的PEM到XML...
(基于python的毕业设计)基于lsb算法与rsa算法的信息隐藏算法实现(django)(源码+说明+演示视频)...(6)信息的提取功能,需要保证在解密的过程中,用户能够通过秘钥的使用来快速的将系统中对应的信息内容进行解密操作。
【基于Python+Django的毕业设计】基于lsb算法与rsa算法的信息隐藏算法实现(源码+录像演示+说明)...(6)信息的提取功能,需要保证在解密的过程中,用户能够通过秘钥的使用来快速的将系统中对应的信息内容进行解密操作。
相对于非对称加密,对称加密具有更高的加解密速度,但双方都需要事先知道密钥,密钥在传输过程中可能会被窃取,因此安全性没有非对称加密高。 常见的对称加密算法:DES,AES,3DES等等 非对称加密算法: 文件加密...
源码亲测可用,可做计算机毕业设计、课程设计等参考。 【项目技术】 python+Django+mysql+B/S+...(6)信息的提取功能,需要保证在解密的过程中,用户能够通过秘钥的使用来快速的将系统中对应的信息内容进行解密操作。
基于Cython的快速国密算法Python实现,目前支持SM2, SM3, SM4(ECB、CBC) #### 安装教程 ``` pip install fastgm ``` #### 使用说明 ##### SM2 SM2是国家密码管理局发布的椭圆曲线公钥密码算法。对标RSA 使用...
在实际操作中,开发者还需要了解如何在代码中使用这些密钥,如使用Java或Python等编程语言的相应库来处理加密和解密过程。此外,安全存储私钥也非常重要,因为它关乎到账户的安全,一旦泄露,可能导致资金损失。 ...