RSA加密与签名的区别

编程入门 行业动态 更新时间:2024-10-27 17:11:06

RSA加密与签名的<a href=https://www.elefans.com/category/jswz/34/1769972.html style=区别"/>

RSA加密与签名的区别

文章目录

  • 一、签名验签原理
  • 二 RSAUtils 工具类
  • 三、通过x509Certificate来获取CA证书的基本信息
  • 四、 通过公钥获取公钥长度

一、签名验签原理

签名的本质其实就是加密,但是由于签名无需还原成明文,因此可以在加密前进行哈希处理。所以签名其实就是哈希+加密,而验签就是哈希+解密+比较。

签名过程:对明文做哈希,拼接头信息,用私钥进行加密,得到签名。

验签过程:用公钥解密签名,然后去除头信息,对明文做哈希,比较2段哈希值是否相同,相同则验签成功。
代码编写: Cipher 用于加密 Signature 用于签名

二 RSAUtils 工具类

package com.example.tr34.application.utils;import android.util.Base64;import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
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.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher;/*** date:2020/9/4 0004* author:wsm (Administrator)* funcation: 私钥有问题,base64解码失败*/public class RSAUtils {private static String RSA = "RSA";/*** *** RSA最大加密大小*/private final static int MAX_ENCRYPT_BLOCK = 117;/*** *** RSA最大解密大小*/private final static int MAX_DECRYPT_BLOCK = 128;/*** 随机生成RSA密钥对(默认密钥长度为1024)** @return*/public static KeyPair generateRSAKeyPair() {return generateRSAKeyPair(1024);}/*** 随机生成RSA密钥对** @param keyLength 密钥长度,范围:512~2048<br>*                  一般1024* @return*/public static KeyPair generateRSAKeyPair(int keyLength) {try {KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);kpg.initialize(keyLength);return kpg.genKeyPair();} catch (NoSuchAlgorithmException e) {e.printStackTrace();return null;}}/*** 用公钥加密 <br>* 每次加密的字节数,不能超过密钥的长度值减去11** @param data   需加密数据的byte数据* @param publicKey 公钥* @return 加密后的byte型数据*/public static byte[] encryptData(byte[] data, PublicKey publicKey) {try {Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");// 编码前设定编码方式及密钥cipher.init(Cipher.ENCRYPT_MODE, publicKey);// 传入编码数据并返回编码结果return cipher.doFinal(data);} catch (Exception e) {e.printStackTrace();return null;}}/*** 用私钥解密** @param encryptedData 经过encryptedData()加密返回的byte数据* @param privateKey    私钥* @return*/public static byte[] decryptData(byte[] encryptedData, PrivateKey privateKey) {try {Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(encryptedData);} catch (Exception e) {return null;}}/*** 通过公钥byte[](publicKey.getEncoded())将公钥还原,适用于RSA算法** @param keyBytes* @return* @throws NoSuchAlgorithmException* @throws InvalidKeySpecException*/public static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException,InvalidKeySpecException {X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(RSA);PublicKey publicKey = keyFactory.generatePublic(keySpec);return publicKey;}/*** 通过私钥byte[]将公钥还原,适用于RSA算法** @param keyBytes* @return* @throws NoSuchAlgorithmException* @throws InvalidKeySpecException*/public static PrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException,InvalidKeySpecException {PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(RSA);PrivateKey privateKey = keyFactory.generatePrivate(keySpec);return privateKey;}/*** 使用N、e值还原公钥** @param modulus* @param publicExponent* @return* @throws NoSuchAlgorithmException* @throws InvalidKeySpecException*/public static PublicKey getPublicKey(String modulus, String publicExponent)throws NoSuchAlgorithmException, InvalidKeySpecException {BigInteger bigIntModulus = new BigInteger(modulus);BigInteger bigIntPrivateExponent = new BigInteger(publicExponent);RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent);KeyFactory keyFactory = KeyFactory.getInstance(RSA);PublicKey publicKey = keyFactory.generatePublic(keySpec);return publicKey;}/*** 使用N、d值还原私钥** @param modulus* @param privateExponent* @return* @throws NoSuchAlgorithmException* @throws InvalidKeySpecException*/public static PrivateKey getPrivateKey(String modulus, String privateExponent)throws NoSuchAlgorithmException, InvalidKeySpecException {BigInteger bigIntModulus = new BigInteger(modulus);BigInteger bigIntPrivateExponent = new BigInteger(privateExponent);RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent);KeyFactory keyFactory = KeyFactory.getInstance(RSA);PrivateKey privateKey = keyFactory.generatePrivate(keySpec);return privateKey;}/*** 从字符串中加载公钥** @param publicKeyStr 公钥数据字符串* @throws Exception 加载公钥时产生的异常*/public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {try {byte[] buffer = Base64.decode(publicKeyStr,Base64.DEFAULT);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 (NullPointerException e) {throw new Exception("公钥数据为空");}}/*** 从字符串中加载私钥<br>* 加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。** @param privateKeyStr* @return* @throws Exception*/public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception {try {byte[] buffer = Base64.decode(privateKeyStr,Base64.DEFAULT);// X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);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 (NullPointerException e) {throw new Exception("私钥数据为空");}}/*** 用公钥分段加密 <br>* 每次加密的字节数,不能超过密钥的长度值减去11** @param data 需加密数据的byte数据* @param publicKey 公钥* @return 加密后的byte型数据*/public static byte[] PublicSubData(byte[] data, PublicKey publicKey) {try {Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");// 编码前设定编码方式及密钥cipher.init(Cipher.ENCRYPT_MODE, publicKey);// 传入编码数据并返回编码结果
//            return cipher.doFinal(data);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[] decryptedData = out.toByteArray();out.close();return decryptedData;} catch (Exception e) {e.printStackTrace();return null;}}/*** 用私钥分段解密** @param encryptedData 经过encryptedData()加密返回的byte数据* @param privateKey    私钥* @return*/public static byte[] PrivateSubData(byte[] encryptedData, PrivateKey privateKey) {try {Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.DECRYPT_MODE, privateKey);
//            return cipher.doFinal(encryptedData);// 返回UTF-8编码的解密信息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;} catch (Exception e) {return null;}}/*** 从文件中输入流中加载公钥** @param in 公钥输入流* @throws Exception 加载公钥时产生的异常*/public static PublicKey loadPublicKey(InputStream in) throws Exception {try {return loadPublicKey(readKey(in));} catch (IOException e) {throw new Exception("公钥数据流读取错误");} catch (NullPointerException e) {throw new Exception("公钥输入流为空");}}/*** 从文件中加载私钥** @param in 私钥文件名* @return 是否成功* @throws Exception*/public static PrivateKey loadPrivateKey(InputStream in) throws Exception {try {return loadPrivateKey(readKey(in));} catch (IOException e) {throw new Exception("私钥数据读取错误");} catch (NullPointerException e) {throw new Exception("私钥输入流为空");}}/*** 读取密钥信息** @param in* @return* @throws IOException*/private static String readKey(InputStream in) throws IOException {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 sb.toString();}/*** 打印公钥信息** @param publicKey*/public static void printPublicKeyInfo(PublicKey publicKey) {RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;System.out.println("----------RSAPublicKey----------");System.out.println("Modulus.length=" + rsaPublicKey.getModulus().bitLength());System.out.println("Modulus=" + rsaPublicKey.getModulus().toString());System.out.println("PublicExponent.length=" + rsaPublicKey.getPublicExponent().bitLength());System.out.println("PublicExponent=" + rsaPublicKey.getPublicExponent().toString());}public static void printPrivateKeyInfo(PrivateKey privateKey) {RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;System.out.println("----------RSAPrivateKey ----------");System.out.println("Modulus.length=" + rsaPrivateKey.getModulus().bitLength());System.out.println("Modulus=" + rsaPrivateKey.getModulus().toString());System.out.println("PrivateExponent.length=" + rsaPrivateKey.getPrivateExponent().bitLength());System.out.println("PrivatecExponent=" + rsaPrivateKey.getPrivateExponent().toString());}
}

三、通过x509Certificate来获取CA证书的基本信息

     //创建X509工厂类CertificateFactory cf = CertificateFactory.getInstance("X.509");//创建证书对象X509Certificate oCert = (X509Certificate)cf.generateCertificate(inStream);// inStream证书的传入数据inStream.close();SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd");String info = null;//获得证书版本info = String.valueOf(oCert.getVersion());System.out.println("证书版本:"+info);//获得证书序列号info = oCert.getSerialNumber().toString(16);System.out.println("证书序列号:"+info);//获得证书有效期Date beforedate = oCert.getNotBefore();info = dateformat.format(beforedate);System.out.println("证书生效日期:"+info);Date afterdate = oCert.getNotAfter();info = dateformat.format(afterdate);System.out.println("证书失效日期:"+info);//获得证书主体信息info = oCert.getSubjectDN().getName();System.out.println("证书拥有者:"+info);//获得证书颁发者信息info = oCert.getIssuerDN().getName();System.out.println("证书颁发者:"+info);//获得证书签名算法名称info = oCert.getSigAlgName();System.out.println("证书签名算法:"+info);byte[] byt = oCert.getExtensionValue("1.2.86.11.7.9");String strExt = new String(byt);System.out.println("证书扩展域:" + strExt);byt = oCert.getExtensionValue("1.2.86.11.7.1.8");String strExt2 = new String(byt);System.out.println("证书扩展域2:" + strExt2);

四、 通过公钥获取公钥长度

通过X509Certificate.getPublicKey 获取公钥

      /*** Gets the key length of supported keys* @param pk PublicKey used to derive the keysize* @return -1 if key is unsupported, otherwise a number >= 0. 0 usually means the length can not be calculated,* for example if the key is an EC key and the "implicitlyCA" encoding is used.*/public static int getKeyLength(final PublicKey pk) {int len = -1;if (pk instanceof RSAPublicKey) {final RSAPublicKey rsapub = (RSAPublicKey) pk;len = rsapub.getModulus().bitLength();} else if (pk instanceof JCEECPublicKey) {final JCEECPublicKey ecpriv = (JCEECPublicKey) pk;final org.bouncycastle.jce.spec.ECParameterSpec spec = ecpriv.getParameters();if (spec != null) {len = spec.getN().bitLength();} else {// We support the key, but we don't know the key lengthlen = 0;}} else if (pk instanceof ECPublicKey) {final ECPublicKey ecpriv = (ECPublicKey) pk;final java.security.spec.ECParameterSpec spec = ecpriv.getParams();if (spec != null) {len = spec.getOrder().bitLength(); // does this really return something we expect?} else {// We support the key, but we don't know the key lengthlen = 0;}} else if (pk instanceof DSAPublicKey) {final DSAPublicKey dsapub = (DSAPublicKey) pk;if ( dsapub.getParams() != null ) {len = dsapub.getParams().getP().bitLength();} else {len = dsapub.getY().bitLength();}}return len;}

更多推荐

RSA加密与签名的区别

本文发布于:2023-12-05 05:15:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1663186.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:区别   RSA

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!