为什么80%的码农都做不了架构师?>>>   

原则:

1) 公钥加密数据

2)私钥进行签名

3)公私钥互加解密密钥。

JAVA

package com.zlbank.rsa;import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
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.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;import javax.crypto.Cipher;import com.zlbank.tool.Base64Utils;/*** <p>* RSA公钥/私钥/签名工具包* </p>* <p>* 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman)* </p>* <p>* 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>* 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>* 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全* </p>* * @author IceWee* @date 2012-4-26* @version 1.0*/
public class RSAUtils {/*** 加密算法RSA*/public static final String KEY_ALGORITHM = "RSA";/*** 签名算法*/// public static final String SIGNATURE_ALGORITHM = "MD5withRSA";public static final String SIGNATURE_ALGORITHM = "SHA1withRSA";/*** 获取公钥的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;}/*** 从文件中输入流中加载公钥* * @param in*            公钥输入流* @throws Exception*             加载公钥时产生的异常*/public static  RSAPublicKey loadPublicKey(InputStream in) throws Exception {try {BufferedReader br = new BufferedReader(new InputStreamReader(in));String readLine = null;StringBuilder sb = new StringBuilder();while ((readLine = br.readLine()) != null) {if (readLine.charAt(0) == '-') {continue;} else {sb.append(readLine);sb.append('\r');}}return loadPublicKey(sb.toString());} catch (IOException e) {throw new Exception("公钥数据流读取错误");} catch (NullPointerException e) {throw new Exception("公钥输入流为空");}}/*** 从字符串中加载公钥* * @param publicKeyStr*            公钥数据字符串* @throws Exception*             加载公钥时产生的异常*/public  static  RSAPublicKey  loadPublicKey(String publicKeyStr) throws Exception {try {byte[] buffer = Base64Utils.decode(publicKeyStr);KeyFactory keyFactory = KeyFactory.getInstance("RSA");X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);return (RSAPublicKey) keyFactory.generatePublic(keySpec);} catch (NoSuchAlgorithmException e) {throw new Exception("无此算法");} catch (InvalidKeySpecException e) {throw new Exception("公钥非法");} catch (IOException e) {throw new Exception("公钥数据内容读取错误");} catch (NullPointerException e) {throw new Exception("公钥数据为空");}}/*** 从文件中加载私钥* * @param keyFileName*            私钥文件名* @return 是否成功* @throws Exception*/public static RSAPrivateKey  loadPrivateKey(InputStream in) throws Exception {try {BufferedReader br = new BufferedReader(new InputStreamReader(in));String readLine = null;StringBuilder sb = new StringBuilder();while ((readLine = br.readLine()) != null) {if (readLine.charAt(0) == '-') {continue;} else {sb.append(readLine);sb.append('\r');}}return loadPrivateKey(sb.toString());} catch (IOException e) {throw new Exception("私钥数据读取错误");} catch (NullPointerException e) {throw new Exception("私钥输入流为空");}}public static  RSAPrivateKey loadPrivateKey(String privateKeyStr) throws Exception {try {byte[] buffer = Base64Utils.decode(privateKeyStr);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);KeyFactory keyFactory = KeyFactory.getInstance("RSA");return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);} catch (NoSuchAlgorithmException e) {throw new Exception("无此算法");} catch (InvalidKeySpecException e) {throw new Exception("私钥非法");} catch (IOException e) {throw new Exception("私钥数据内容读取错误");} catch (NullPointerException e) {throw new Exception("私钥数据为空");}}/*** <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(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;// 对数据分段解密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;}/*** <p>* 公钥加密* </p>* * @param data*            源数据* @param publicKey*            公钥(BASE64编码)* @return* @throws Exception*/public static byte[] encryptByPublicKey(byte[] data, 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.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;}/*** <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());}}
package com.zlbank.tool;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;import it.sauronsoftware.base64.Base64;/*** <p>* BASE64编码解码工具包* </p>* <p>* 依赖javabase64-1.3.1.jar* </p>* * @author IceWee* @date 2012-5-19* @version 1.0*/
public class Base64Utils {/*** 文件读取缓冲区大小*/private static final int CACHE_SIZE = 1024;/*** <p>* BASE64字符串解码为二进制数据* </p>* * @param base64* @return* @throws Exception*/public static byte[] decode(String base64) throws Exception {return Base64.decode(base64.getBytes());}/*** <p>* 二进制数据编码为BASE64字符串* </p>* * @param bytes* @return* @throws Exception*/public static String encode(byte[] bytes) throws Exception {return new String(Base64.encode(bytes));}/*** <p>* 将文件编码为BASE64字符串* </p>* <p>* 大文件慎用,可能会导致内存溢出* </p>* * @param filePath 文件绝对路径* @return* @throws Exception*/public static String encodeFile(String filePath) throws Exception {byte[] bytes = fileToByte(filePath);return encode(bytes);}/*** <p>* BASE64字符串转回文件* </p>* * @param filePath 文件绝对路径* @param base64 编码字符串* @throws Exception*/public static void decodeToFile(String filePath, String base64) throws Exception {byte[] bytes = decode(base64);byteArrayToFile(bytes, filePath);}/*** <p>* 文件转换为二进制数组* </p>* * @param filePath 文件路径* @return* @throws Exception*/public static byte[] fileToByte(String filePath) throws Exception {byte[] data = new byte[0];File file = new File(filePath);if (file.exists()) {FileInputStream in = new FileInputStream(file);ByteArrayOutputStream out = new ByteArrayOutputStream(2048);byte[] cache = new byte[CACHE_SIZE];int nRead = 0;while ((nRead = in.read(cache)) != -1) {out.write(cache, 0, nRead);out.flush();}out.close();in.close();data = out.toByteArray();}return data;}/*** <p>* 二进制数据写文件* </p>* * @param bytes 二进制数据* @param filePath 文件生成目录*/public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {InputStream in = new ByteArrayInputStream(bytes);   File destFile = new File(filePath);if (!destFile.getParentFile().exists()) {destFile.getParentFile().mkdirs();}destFile.createNewFile();OutputStream out = new FileOutputStream(destFile);byte[] cache = new byte[CACHE_SIZE];int nRead = 0;while ((nRead = in.read(cache)) != -1) {   out.write(cache, 0, nRead);out.flush();}out.close();in.close();}}
package com.zlbank.rsa;import java.util.Map;import com.zlbank.tool.Base64Utils;public class RSATester {static String publicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5wonDXZhItfDmRUlWQCFwjYL/SSb5PYU7x4mtKPzopnUamlDXTVcSbUdFGRr4K6ANNPs3UsviraN/QWmI3vguzd/xWlpIbGnkyAOzS4hErf+cQDHSW2/TAf1MqI0I6p6tjfLpp4jXJj0OcEeeVR1oVXkY3I8vuOW1v0wwByAkpwIDAQAB";static String privateKey="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALnCicNdmEi18OZFSVZAIXCNgv9JJvk9hTvHia0o/OimdRqaUNdNVxJtR0UZGvgroA00+zdSy+Kto39BaYje+C7N3/FaWkhsaeTIA7NLiESt/5xAMdJbb9MB/UyojQjqnq2N8umniNcmPQ5wR55VHWhVeRjcjy+45bW/TDAHICSnAgMBAAECgYBkO9+gRomcemhBqJNY8gPZOtK7s5pPFO4mgpX8lMhbNS6tKyWB956LN+IkG9bcoJWdasA/avLPHsjBKueqTj32AAu0lNCXnJBtFHXY2IAIpSNjOYP2HEsq6FWO9V4eznOcg588Hb4udi5F+Sq8E5werTx0q7PZKou8X31apXgiWQJBAN2y1FGjeGeskwPYpfqIv4xF+u4EPTkGWMNOD3uUqJNzPqg5ETYYXKlfQu5LnNMV0LHUbGl0f0hD70Hv+Xbz8RUCQQDWgDq7lEG7FmwPVVdbQceJJOfCWSLl3liFYRUXvLAVXL1aq3314OMp/m93HtbUj/oVJVJ8pEsAWkKEcS8jFFXLAkAEfS19ZbD3cHAdoNJji0dNoNEe5qkSsYU0ly0LFIyBR9EZ+OXXUZD2wP4K8y7+uy9ZmnKDhB9bqDx8+k3z0aatAkEAmIEUwPbYgO6hJ4mykTREbJJroHcFY89gunvapkTGIHoOOp/A74bTm7DFiTjI3tn6oPwnGG0q0fZaYpWiQNudXwJAfWhC3gaFpFYXZdg9+ysB3i7gIlpWd6CELkUV6YIEmW9V8B9URmDPBMLbjRYpt8Q4vGaPPunteeLfIl3Ld0rXUA==";static {try {
//          Map<String, Object> keyMap = RSAUtils.genKeyPair();
//          publicKey = RSAUtils.getPublicKey(keyMap);
//          privateKey = RSAUtils.getPrivateKey(keyMap);
//          System.out.println("公钥: \n\r" + publicKey);
//          System.out.println("私钥: \n\r" + privateKey);
//
//          publicKey= RSAUtils.loadPublicKey("");
//          privateKey=RSAUtils.loadPrivateKey("");
//          } catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) throws Exception {//test();testSign();}static void test() throws Exception {System.out.println("公钥加密——私钥解密");String source = "123456";System.out.println("\r加密前文字:" + source);byte[] data = source.getBytes();byte[] encodedData = RSAUtils.encryptByPublicKey(data, publicKey);System.out.println("加密后文字:" + Base64Utils.encode(encodedData));byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, privateKey);String target = new String(decodedData);System.out.println("解密后文字: " + target);}static void testSign() throws Exception {System.out.println("私钥加密——公钥解密");String source = "9876543";System.out.println("原文字:" + source);byte[] data = source.getBytes();byte[] encodedData = RSAUtils.encryptByPrivateKey(data, privateKey);System.out.println("加密后:" + Base64Utils.encode(encodedData));byte[] decodedData = RSAUtils.decryptByPublicKey(encodedData, publicKey);String target = new String(decodedData);System.out.println("解密后: " + target);System.out.println("私钥签名——公钥验证签名");String sign = RSAUtils.sign(data, privateKey);System.out.println("签名:" + sign);boolean status = RSAUtils.verify(data, publicKey, sign);System.out.println("验证结果:" + status);}}

关键在测试数据:运行结果如下:签名运用是JAVA常用的SHA1withRSA方式

私钥加密——公钥解密
原文字:9876543
加密后:BuC21nX9C1QaW0M16b+Hxn54lnekLQHD1fNcaQgK7MvHNuQKNiwUQilYsi2vALm/yBEnIsR0SreXWYFFogq75SsbI/4fxF2tFz16JIR5+z5Wdm/uE0AFfQDqVMX2I0aJSKzTRhRmCJgE7+n0ALon/b2WLQfHguxGF8X9WjnqnXM=
解密后: 9876543
私钥签名——公钥验证签名
签名:aO9kIu3T4Q/irSxloqlSw+5Mm7TgNooqqkGFEuIyiFZ+KC2P8RFXnzhr2laggRpWVEEQ4cNysqoSE8uDnc3+Me/Ef4YHjK0F30sas1U8VsLuuBghptB406PZc0aStI7ZMp63AokNN+8FoVQ87ObYzRhkXOoKEy+W4gFjcT/usEg=
验证结果:true

===== >对应的C 运用openssl进行做同样的工作:

先看运行结果:

===============RSA 加密与解密 VS 加签与验签功能 演示=================
RSA加解密------>加密前数据:[9876543]
RSA加解密------>加密后数据:06e0b6d675fd0b541a5b4335e9bf87c67e789677a42d01c3d5f35c69080aeccbc736e40a362c14422958b22daf00b9bfc8112722c4744ab797598145a20abbe52b1b23fe1fc45dad173d7a248479fb3e56766fee1340057d00ea54c5f623468948acd3461466089804efe9f400ba27fdbd962d07c782ec4617c5fd5a39ea9d73
RSA加解密------>解密后数据: 9876543
======================================================
RSA加验签---RSA_sign---> RSA_sign( NID_sha1, src, sizeof(src)-1, sign, &sign_len, key)加签成功 [1]
RSA加验签---RSA_verify--->RSA_verify( NID_sha1, src, sizeof(src)-1, sign, sign_len, key)验签成功 [1]
RSA加验签----->待加签数据: [9876543]
RSA加验签----->手工计算sha1(9876543)=3c776dacfd82b327a679bdf2339cc9477299ebb6
======================================================
签名数据(十六进表现形式): 68ef6422edd3e10fe2ad2c65a2a952c3ee4c9bb4e0368a2aaa418512e23288567e282d8ff111579f386bda56a0811a56544110e1c372b2aa1213cb839dcdfe31efc47f86078cad05df4b1ab3553c56c2eeb81821a6d078d3a3d9734692b48ed9329eb702890d37ef05a1543cece6d8cd18645cea0a132f96e20163713feeb048
RSA加验签--->RSA_verify( NID_sha1, sha1, sha1_len, sign, sign_len, key) is ok
RSA加验签--->RSA_verify( NID_sha1, src, strlen(src), sign, sign_len, key) is error
======================================================
RSA加验签--->签名解密得到的数据:3021300906052b0e03021a050004143c776dacfd82b327a679bdf2339cc9477299ebb6
RSA加验签---> RSA_sign( NID_sha1, sha1, 20, sign, &sign_len, key): 68ef6422edd3e10fe2ad2c65a2a952c3ee4c9bb4e0368a2aaa418512e23288567e282d8ff111579f386bda56a0811a56544110e1c372b2aa1213cb839dcdfe31efc47f86078cad05df4b1ab3553c56c2eeb81821a6d078d3a3d9734692b48ed9329eb702890d37ef05a1543cece6d8cd18645cea0a132f96e20163713feeb048
RSA加验签---> RSA_sign( NID_sha1, sha1, 20, sign, &sign_len, key) 对应BASE64数据[aO9kIu3T4Q/irSxloqlSw+5Mm7TgNooqqkGFEuIyiFZ+KC2P8RFXnzhr2laggRpWVEEQ4cNysqoSE8uDnc3+Me/Ef4YHjK0F30sas1U8VsLuuBghptB406PZc0aStI7ZMp63AokNN+8FoVQ87ObYzRhkXOoKEy+W4gFjcT/usEg=]
RSA加验签--->直接解密加签数据:3021300906052b0e03021a050004143c776dacfd82b327a679bdf2339cc9477299ebb6
======================================================
RSA加验签---> RSA_sign( NID_sha1, src, strlen(src), sign, &sign_len, key): 56eec6b2d018056d33c6dd5ddd4277ab6828972154e77a6b08f88fbc4cdd69e0d4657ca01983193e1b8115ad2bbc6aa353da41510aaa74a42947c1903d9c0d61626348592ae9f4dabd6bbb71020c78f6afbef7cd70a6b1367d9dccd75f68516ebc2e0ea7a8e090eb424abbd6cdcdbeace86288a0cfd09568f78dabd15472767f
RSA加验签---> RSA_sign( NID_sha1, src, strlen(src), sign, &sign_len, key) 对应BASE64数据[Vu7GstAYBW0zxt1d3UJ3q2golyFU53prCPiPvEzdaeDUZXygGYMZPhuBFa0rvGqjU9pBUQqqdKQpR8GQPZwNYWJjSFkq6fTavWu7cQIMePavvvfNcKaxNn2dzNdfaFFuvC4Op6jgkOtCSrvWzc2+rOhiiKDP0JVo942r0VRydn8=]
RSA加验签--->直接解密加签数据:3014300906052b0e03021a0500040739383736353433

代码如下:

/** rsa_sign_test.c**  Created on: 2015年11月27日*      Author: mengfh*      1)验证RSA加密+解密*      2)验证RSA所对应java中SHA1WITHRSA功能加签与验签*/#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <assert.h>
#include<stdlib.h>#define SetKey \key->n = BN_bin2bn(n, sizeof(n)-1, key->n); \
key->e = BN_bin2bn(e, sizeof(e)-1, key->e); \
key->d = BN_bin2bn(d, sizeof(d)-1, key->d); \
key->p = BN_bin2bn(p, sizeof(p)-1, key->p); \
key->q = BN_bin2bn(q, sizeof(q)-1, key->q); \
key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1); \
key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1); \
key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp); \
return 0;/*功能:解密成功返回0,否则返回-1* 参数:* pData:待解码数据* nLeng:待解码数据长度* linebreaks:待解码数据是否以64字节换行 (0不换行; 1换行)* pOutBufffer:解码后数据* pBufferLenth:解码后数据长度,传入时为pOutBufffer大小,传出为解码后数据长度*/
int Base64Encode(unsigned char *pData, int nLeng, int linebreaks, char * pOutBufffer, int *pBufferLenth)
{int res = -1;BIO *bmem, *b64;BUF_MEM *bptr;b64 = BIO_new(BIO_f_base64());if (!b64)return res;if (!linebreaks){BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);}bmem = BIO_new(BIO_s_mem());if (bmem){b64 = BIO_push(b64, bmem);if (BIO_write(b64, pData, nLeng) == nLeng){(void) BIO_flush(b64);BIO_get_mem_ptr(b64, &bptr);if (*pBufferLenth > bptr->length){memcpy(pOutBufffer, bptr->data, bptr->length);pOutBufffer[bptr->length] = 0;res = 0;}*pBufferLenth = bptr->length + 1;}}BIO_free_all(b64);return res;
}/***功能:编码成功返0 , 否则返-1* pData:待编码数据* nLeng:待编码数据长度* linebreaks:待编码数据是否以64字节换行 (0不换行; 1换行)* pOutBufffer:编码后数据* pBufferLenth:编码后数据长度,传入时为pOutBufffer大小,传出为编码后数据长度*/
int Base64Decode(char *pData, int nLeng, int linebreaks, unsigned char * pOutBufffer, int *pBufferLenth)
{int res = -1;BIO *bmem;BIO *b64;if (nLeng == 0)nLeng = strlen(pData);int nMaxLen = (nLeng * 6 + 7) / 8;int nMiniLen;unsigned char *buf = malloc(nMaxLen * sizeof(unsigned char));if (buf){b64 = BIO_new(BIO_f_base64());if (b64){if (!linebreaks){BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);}bmem = BIO_new_mem_buf((char*) pData, nLeng);b64 = BIO_push(b64, bmem);nMiniLen = BIO_read(b64, buf, nMaxLen);if (*pBufferLenth >= nMiniLen){memcpy(pOutBufffer, buf, nMiniLen);res = 0;}*pBufferLenth = nMiniLen;BIO_free_all(b64);}free(buf);}return res;
}//构建RSA公、私钥信息
static int key5(RSA *key)
{//密钥中变量static unsigned char n[] ="\x9c\xb5\xd4\x87\x70\xb6\x43\x03\x49\x5e\xe8\x40\xbc\xbf\x15\x79\x9e\xb2\x18\x0d\xfa\xde\xf7\xb2\x37\xd0\x22\xdb\xd4\xef\x2d\x79\x63\xdb\x38\x2b\xed\x05\xe5\x14\x0b\x9a\x80\x5c\x75\x11\xef\x1b\x89\x5b\x40\xb7\x1c\x22\x7d\x84\x59\xbc\xcc\xb5\xca\x63\xbd\x7b\xdf\x1e\x3a\x72\x13\x86\x93\xa9\x9c\xc7\xcb\x48\x3d\x8b\x8c\xa9\x4c\xce\xd7\xca\xc0\xb0\x62\x7a\x95\x7a\xd7\xbd\x27\x82\x91\x40\x90\x35\xb1\xe4\xab\x5f\xbb\x06\x29\x01\xf4\x91\xe5\x15\x5f\xd3\xc2\x13\x38\xaf\x1f\x75\x88\x47\xd1\x04\xd2\xb3\x71\xa0\x9e\xc7";static unsigned char e[] = "\x00\x01\x00\x01";static unsigned char d[] ="\x09\x33\x83\xef\x0f\xe7\x23\xb8\x25\xae\xb4\xe4\x58\x30\xc0\x0a\x0c\x0f\x58\xea\x39\x38\xae\x42\x80\x94\x6f\xf7\x88\x61\x22\xc2\x65\xe2\x91\x41\xc3\x00\xfd\x9a\x57\xb4\x12\xa5\x5b\x1a\x5a\x77\xbb\x70\xe8\x33\xd8\x2b\x0e\x43\x9f\x21\x3e\xc3\xcd\xc6\x5d\x71\xb8\xec\x6e\xea\x5f\x17\xa5\xe1\x43\xeb\xdd\x71\xa4\x6f\xed\x09\xf0\x8b\xbe\xd9\x26\xb5\x70\x9b\xab\x42\x70\x70\x71\xd4\x14\x8f\xa8\x2c\xc4\x23\x21\x70\x1f\xd7\xef\xfd\x6b\x02\x40\x8b\xf4\x77\x5c\x78\x08\x80\x8b\x7d\x7e\x7a\xb2\x14\xe0\xf6\x94\xf2\x56\x81";static unsigned char p[] ="\xd6\x8c\xf3\x60\x76\x5b\x6e\x55\xde\x5a\xf7\x43\x95\x6b\x5e\xc0\xd9\x5a\xcd\xd8\x03\xd3\x65\xcb\x1d\xf6\xfe\x57\x39\x6c\xfd\x72\x06\x8b\xe8\x2e\x05\xfd\xe4\x7c\x39\x94\xa2\xea\xb8\x4c\xf5\xd6\xdc\xd7\x9a\xb8\xef\x05\xd9\xef\x96\xfa\x91\xa3\xb6\x9a\xd4\x19";static unsigned char q[] ="\xba\xfc\x43\xf4\x79\x60\x09\x97\x37\x6e\x55\x83\xbb\xb6\xb3\x5f\x4c\x39\x00\x93\x19\x90\x64\x65\x3a\xf7\xa0\xca\x5e\x9d\x66\xd9\xee\x7d\xdb\xd0\xe2\xe7\x57\x55\x41\x90\xc7\x4b\xed\x91\x42\xea\x34\x93\x1a\x76\xb8\xd0\xf2\x74\xed\xf5\xd3\xb9\xa6\x34\x65\xdf";static unsigned char dmp1[] ="\x4f\xfd\x89\x17\xa3\xc8\xfe\xe0\x00\xe0\xc5\x63\x6b\x27\xf6\xd1\xcb\xb7\xb1\x1b\x22\x82\x04\x67\xb0\x2a\x50\x35\x50\xf1\xb3\xa4\x79\x90\x5b\xe6\x1c\xd1\xc6\x08\x12\xa7\xb9\xfd\xec\xec\xb4\x93\x81\x0e\xd9\x5e\xad\xae\xee\xcc\x06\xec\x30\xb4\x6a\xf6\x5a\xb1";static unsigned char dmq1[] ="\x60\x9b\x5d\x70\xbe\x15\x04\x5f\x80\x60\x1d\x06\x86\xc1\x8a\x43\x3e\x5a\x65\x15\x9b\x2b\xa2\xf3\x3a\x58\x1e\x56\xf0\x33\x5a\xa4\x56\x37\xe8\x8e\x2f\xed\x5e\x8d\xc9\xe6\x47\x51\xcf\x58\x31\xbe\x57\x93\x79\x24\xc5\xb0\x0e\xd4\xa2\xed\x53\x8a\xa3\x78\x86\xf9";static unsigned char iqmp[] ="\x28\xc6\xca\x44\x40\x7a\xad\x4c\x74\x4d\xeb\x2d\xaa\xd7\xc8\x43\xef\x4a\x12\x44\x0a\x89\xb8\x12\x11\x7f\x40\x91\x9a\xe1\x4a\xfe\xe2\xe5\x3e\x6c\x7f\x07\x49\x04\xc9\x95\x8a\x4e\xa5\x7f\x3c\x8f\xea\xbd\x71\x2e\xca\x7a\x37\xdf\x99\x05\x2f\x0c\x03\x11\x6d\x5d";SetKey;
}//验名数据(测试用 JAVA测试代码生成)
char *signData ="aO9kIu3T4Q/irSxloqlSw+5Mm7TgNooqqkGFEuIyiFZ+KC2P8RFXnzhr2laggRpWVEEQ4cNysqoSE8uDnc3+Me/Ef4YHjK0F30sas1U8VsLuuBghptB406PZc0aStI7ZMp63AokNN+8FoVQ87ObYzRhkXOoKEy+W4gFjcT/usEg=";/*** 加解密* 加签与验签*/
int main(int argc, char *argv[])
{int err = 0;int v;RSA *key;unsigned char rsaDecodeData[256];unsigned char des[256];unsigned char sign[1024], sha1[256];unsigned char src[] = "9876543";unsigned char ctext_ex[256];unsigned char tmpBuf[2560];int plen;int clen = 0;int ret;int n;int i;int sign_len, r, len,sha1_len;FILE *fprivate, *fpbulic;EVP_PKEY *pkey;fprintf(stderr, "===============RSA 加密与解密 VS 加签与验签功能 演示=================\n");//1:生成RSA密钥key = RSA_new();{
//        key5(key);}//从文件中直接取公、私钥信息{if ((fprivate = fopen("./private.pem", "r")) == NULL){fprintf(stderr, " open fprivate file error \n");return -1;}if ((fpbulic = fopen("./public.pem", "r")) == NULL){fprintf(stderr, " open fpbulic file error \n");return -1;}if ((PEM_read_RSAPrivateKey(fprivate, &key, NULL, NULL)) == NULL){fprintf(stderr, " PEM_read_RSAPrivateKeyerror error\n");return -1;}PEM_read_RSAPublicKey(fpbulic, &key, NULL, NULL);
//      if ((PEM_read_RSAPublicKey(fpbulic, &key, NULL, NULL)) == NULL)
//      {
//          fprintf(stderr, " PEM_read_RSAPublicKey error \n");
//          return -1;
//      }}//----------------------加解密//加密数据======================================================fprintf(stderr, "RSA加解密------>加密前数据:[%s]\n", src);memset(des, 0 ,sizeof(des));ret = RSA_private_encrypt(sizeof(src) - 1, src, des, key,RSA_PKCS1_PADDING);if (ret != 128)   //模数长度{fprintf(stderr,"PKCS#1 v1.5 encryption failed!\n");err = 1;goto next;}//加密后的数据fprintf(stderr, "RSA加解密------>加密后数据:");for (i = 0; i < ret; i++){fprintf(stderr,"%02x", des[i]);}fprintf(stderr,"\n");memset(tmpBuf, 0 ,sizeof(tmpBuf));ret = RSA_public_decrypt(ret, des, tmpBuf, key,RSA_PKCS1_PADDING);if (ret <=0){printf("PKCS#1 v1.5 decryption failed!\n");err = 1;}tmpBuf[ret] = '\0';    //字符串结尾printf("RSA加解密------>解密后数据: %s\n", tmpBuf);fprintf(stderr, "======================================================\n");//======================================================//自带RSA_sign vs  RSA_verifymemset(sign, 0 ,sizeof(sign));r = RSA_sign( NID_sha1, src, sizeof(src)-1, sign, &sign_len, key);assert(0 != r);printf("RSA加验签---RSA_sign---> RSA_sign( NID_sha1, src, sizeof(src)-1, sign, &sign_len, key)加签成功 [%d]\n", r);r = RSA_verify( NID_sha1, src, sizeof(src)-1, sign, sign_len, key);assert(0 != r);printf("RSA加验签---RSA_verify--->RSA_verify( NID_sha1, src, sizeof(src)-1, sign, sign_len, key)验签成功 [%d]\n", r);// 测试JAVA 签名数据================================================fprintf(stderr, "RSA加验签----->待加签数据: [%s]\n", src);//SHA1memset(sha1, 0, sizeof(sha1));SHA1(src, strlen(src), sha1);sha1_len =20;fprintf(stderr, "RSA加验签----->手工计算sha1(%s)=", src);for (i = 0; i < sha1[i] != '\0'; i++)fprintf(stderr,"%02x", sha1[i]);fprintf(stderr,"\n");fprintf(stderr, "======================================================\n");//解析加签数据memset(sign, 0 ,sizeof(sign));sign_len = sizeof(sign);if( Base64Decode(signData, strlen(signData), 0, sign, &sign_len)<0){fprintf(stderr, " Base64Decode error \n");return -1;}fprintf(stderr, "签名数据(十六进表现形式): ");for (i = 0; i < sign_len; i++)fprintf(stderr,"%02x", sign[i]);fprintf(stderr,"\n");//对比二种验签数据源if( RSA_verify( NID_sha1, sha1, sha1_len, sign, sign_len, key) ==1){fprintf(stderr,"RSA加验签--->RSA_verify( NID_sha1, sha1, sha1_len, sign, sign_len, key) is ok\n");}else{fprintf(stderr,"RSA加验签--->RSA_verify( NID_sha1, sha1, sha1_len, sign, sign_len, key) is error\n");}if( RSA_verify( NID_sha1, src, strlen(src), sign, sign_len, key) ==1){fprintf(stderr,"RSA加验签--->RSA_verify( NID_sha1, src, strlen(src), sign, sign_len, key) is ok\n");}else{fprintf(stderr,"RSA加验签--->RSA_verify( NID_sha1, src, strlen(src), sign, sign_len, key) is error\n");}fprintf(stderr, "======================================================\n");//将签名数据RSA解密memset(tmpBuf, 0, sizeof(tmpBuf));if((ret = RSA_public_decrypt(sign_len, sign, tmpBuf, key, RSA_PKCS1_PADDING))<=0){fprintf(stderr, " RSA_public_decrypt error \n");return -1;}fprintf(stderr, "RSA加验签--->签名解密得到的数据:");for (i = 0; i < ret; i++){fprintf(stderr,"%02x", tmpBuf[i]);}fprintf(stderr,"\n");//进行数据加签操作memset(sign, 0, sizeof(sign));sign_len = -1;if(1!= RSA_sign( NID_sha1, sha1, sha1_len, sign, &sign_len, key)){fprintf(stderr, " RSA_sign error \n");return -1;}fprintf(stderr,"RSA加验签---> RSA_sign( NID_sha1, sha1, 20, sign, &sign_len, key): ");for (i = 0; i < sign_len; i++){fprintf(stderr,"%02x", sign[i]);}fprintf(stderr,"\n");memset(tmpBuf, 0, sizeof(tmpBuf));len = sizeof(tmpBuf);if(Base64Encode(sign, sign_len, 0, tmpBuf, &len)<0){fprintf(stderr, " Base64Encode error \n");return -1;}fprintf(stderr, "RSA加验签---> RSA_sign( NID_sha1, sha1, 20, sign, &sign_len, key) 对应BASE64数据[%s]\n", tmpBuf);memset(tmpBuf, 0 ,sizeof(tmpBuf));ret = RSA_public_decrypt(sign_len, sign, tmpBuf, key, RSA_PKCS1_PADDING);fprintf(stderr, "RSA加验签--->直接解密加签数据:");for (i = 0; i < ret; i++){fprintf(stderr,"%02x", tmpBuf[i]);}fprintf(stderr,"\n");fprintf(stderr, "======================================================\n");//进行数据加签操作memset(sign, 0, sizeof(sign));sign_len = -1;if(1!= RSA_sign( NID_sha1, src, strlen(src), sign, &sign_len, key)){fprintf(stderr, " RSA_sign error \n");return -1;}fprintf(stderr,"RSA加验签---> RSA_sign( NID_sha1, src, strlen(src), sign, &sign_len, key): ");for (i = 0; i < sign_len; i++){fprintf(stderr,"%02x", sign[i]);}fprintf(stderr,"\n");memset(tmpBuf, 0, sizeof(tmpBuf));len = sizeof(tmpBuf);if(Base64Encode(sign, sign_len, 0, tmpBuf, &len)<0){fprintf(stderr, " Base64Encode error \n");return -1;}fprintf(stderr, "RSA加验签---> RSA_sign( NID_sha1, src, strlen(src), sign, &sign_len, key) 对应BASE64数据[%s]\n", tmpBuf);//将签名数据RSA解密memset(tmpBuf, 0 ,sizeof(tmpBuf));ret = RSA_public_decrypt(sign_len, sign, tmpBuf, key, RSA_PKCS1_PADDING);fprintf(stderr, "RSA加验签--->直接解密加签数据:");for (i = 0; i < ret; i++){fprintf(stderr,"%02x", tmpBuf[i]);}fprintf(stderr,"\n");fprintf(stderr, "======================================================\n");next://公钥和私钥输出为 PEM 格式:PEM_write_RSAPrivateKey(stdout, key, NULL, NULL, 0, NULL, NULL);PEM_write_RSAPublicKey(stdout, key);//释放申请的内存RSA_free(key);if (err)fprintf(stderr,"ERROR: %d\n", err);return err;
}

转载于:https://my.oschina.net/3pgp/blog/537873

RSA加解密VS加签与验签相关推荐

  1. 前后端RSA互相加解密、加签验签、密钥对生成(Java)

    目录 一.序言 二.关于PKCS#1和PKCS#8格式密钥 1.简介 2.区别 二.关于JSEncrypt 三.关于jsrsasign 四.前端RSA加解密.加验签示例 1.相关依赖 2.crypto ...

  2. 聊一聊关于加解密、加签验签的那些事

    面对MD5.SHA.DES.AES.RSA等等这些名词你是否有很多问号?这些名词都是什么?还有什么公钥加密.私钥解密.私钥加签.公钥验签.这些都什么鬼?或许在你日常工作没有听说过这些名词,但是一旦你要 ...

  3. 速看: 加解密、加签验签,你想要的都在这了

    点击蓝色"java大数据修炼之道"关注我哟加个"星标",每晚21:00,一起学技术 来源: jianshu.com/p/5e9fe1fff6a3 作者: 不学无 ...

  4. java证书加签_证书加签、验签、加密、解密Demo

    package sslSocket; import javax.crypto.Cipher; import java.io.FileInputStream; import java.security. ...

  5. 关于加解密、加签验签的那些事

    来源:r6d.cn/acJae 面对MD5.SHA.DES.AES.RSA等等这些名词你是否有很多问号?这些名词都是什么?还有什么公钥加密.私钥解密.私钥加签.公钥验签.这些都什么鬼?或许在你日常工作 ...

  6. RSA签名加签、验签实现

    一.引言 之前简单写了一个关于参数名ASCII码从小到大排序的文章(https://blog.csdn.net/sinat_34974437/article/details/104756995),该方 ...

  7. 千万别再问加解密、加签验签的问题了,全给你整理好了

    点击上方☝码猿技术专栏 轻松关注,设为星标! 及时获取有趣有料的技术 来源:r6d.cn/acJae 面对MD5.SHA.DES.AES.RSA等等这些名词你是否有很多问号?这些名词都是什么?还有什么 ...

  8. 公钥、私钥、证书、加密、解密、加签、验签

    https://blog.csdn.net/woniu211111/article/details/108114402 明文.密文.密钥.加密.解密 明文:指没有经过加密的信息/数据. 密文:明文被加 ...

  9. 加签,验签,CA认证中心流程

    概述: 本文主要是为了说明,三者在请求中的位置,以便于更好的理解三者的概念和作用. 信息安全三要素: 有效性(Availability):保证合法用户对信息和资源的使用不会被不正当地拒绝. 保密性(C ...

  10. 前后端分离技术之加签,验签,防篡改

    上一篇讲解了加密解密,这次来个加签验签,实际项目里,我们采用的是react 和nodejs 来进行加签验签,用的jsrsasign库,下面贴点核心代码 react加签 nodejs验签 实际应用在no ...

最新文章

  1. 简单看看 Go 1.17 的新版调用规约
  2. 前端JavaScripts基础知识点
  3. qt4.7 mysql_详解Qt 4.7编译和访问Mysql驱动
  4. FI常用T-CODE
  5. C#设计模式之5-单例模式
  6. 2012年3月份工作总结 ~ 之 ~ PDF 作业对应 (虽然这个作业没有什么意思,但是非常值得总结)
  7. django中url与view配置方法
  8. 超详细的抖音养号上热门技巧,看完这一篇就够了
  9. linux如何自定义桌面,如何自定义 GNOME 3 桌面? | Linux 中国
  10. Ps流转H264流 代码实现
  11. 设计模式解密(17)- 备忘录模式
  12. android exoplayer最好用的视频播放器,倍速播放
  13. 【阅读笔记】项亮前辈的《推荐系统实战》
  14. App应用中拨打电话
  15. c语言入门自学免费app,C语言入门学习最新版下载-C语言入门学习app手机版v1.0.2 安卓版-腾飞网...
  16. flashback的配置
  17. spreadtrum展信平台加密Secure boot流程
  18. IIC/I2C总线实验
  19. 因果推断—现代统计的思想飞跃:过去、现在到未来(伯克利丁鹏博士万字长文)...
  20. 火车站的江湖,远比你想象的深

热门文章

  1. python DataFrame获取行数、列数、索引及第几行第几列的值
  2. PyTorch:tensor-基本操作
  3. 判断服务器芯片还是民用芯片,抢鲜看,Xeon E3-1230对比I7 2600评测
  4. python之禅源代码_python之禅
  5. Flutter进阶第14篇:支付宝支付【下】
  6. Dart基础第11篇:抽象类 多态 以及接口
  7. elipse开发android 如何查看报错信息
  8. C语言 — 编程规范、标识符命名规范
  9. luogu p1799 数列_NOI导刊2010提高(06)
  10. BZOJ 2756: [SCOI2012]奇怪的游戏