当前位置:首页>开发>正文

怎么用java实现RSA加密 RSA算法 写出加解密过程

2023-05-03 10:36:36 互联网 未知 开发

 怎么用java实现RSA加密 RSA算法 写出加解密过程

怎么用java实现RSA加密

流程分析: 
    1、甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。 
    2、甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。 
    3、乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。
    通过java代码实现如下:
import java.security.Key  
import java.security.KeyFactory  
import java.security.KeyPair  
import java.security.KeyPairGenerator  
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.HashMap  
import java.util.Map  
import javax.crypto.Cipher  
/** *//**
* RSA安全编码组件
*  
* @version 1.0
* @since 1.0
*/
public abstract class RSACoder extends Coder {  
    public static final String KEY_ALGORITHM = "RSA"  
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA"  
    private static final String PUBLIC_KEY = "RSAPublicKey"  
    private static final String PRIVATE_KEY = "RSAPrivateKey"  
    /** *//**
    * 用私钥对信息生成数字签名
    *  
    * @param data
    *    加密数据
    * @param privateKey
    *    私钥
    *  
    * @return
    * @throws Exception
    */
    public static String sign(byte[] data, String privateKey) throws Exception {  
    // 解密由base64编码的私钥  
    byte[] keyBytes = decryptBASE64(privateKey)  
    // 构造PKCS8EncodedKeySpec对象  
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)  
    // KEY_ALGORITHM 指定的加密算法  
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)  
    // 取私钥匙对象  
    PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec)  
    // 用私钥对信息生成数字签名  
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM)  
    signature.initSign(priKey)  
    signature.update(data)  
    return encryptBASE64(signature.sign())  
    }  
    /** *//**
    * 校验数字签名
    *  
    * @param data
    *    加密数据
    * @param publicKey
    *    公钥
    * @param sign
    *    数字签名
    *  
    * @return 校验成功返回true 失败返回false
    * @throws Exception
    *  
    */
    public static boolean verify(byte[] data, String publicKey, String sign)  
    throws Exception {  
    // 解密由base64编码的公钥  
    byte[] keyBytes = decryptBASE64(publicKey)  
    // 构造X509EncodedKeySpec对象  
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes)  
    // KEY_ALGORITHM 指定的加密算法  
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)  
    // 取公钥匙对象  
    PublicKey pubKey = keyFactory.generatePublic(keySpec)  
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM)  
    signature.initVerify(pubKey)  
    signature.update(data)  
    // 验证签名是否正常  
    return signature.verify(decryptBASE64(sign))  
    }  
    /** *//**
    * 解密

* 用私钥解密 http://www.5a520.cn http://www.feng123.com
    *  
    * @param data
    * @param key
    * @return
    * @throws Exception
    */
    public static byte[] decryptByPrivateKey(byte[] data, String key)  
    throws Exception {  
    // 对密钥解密  
    byte[] keyBytes = decryptBASE64(key)  
    // 取得私钥  
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)  
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)  
    Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec)  
    // 对数据解密  
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm())  
    cipher.init(Cipher.DECRYPT_MODE, privateKey)  
    return cipher.doFinal(data)  
    }  
    /** *//**
    * 解密

    * 用私钥解密
    *  
    * @param data
    * @param key
    * @return
    * @throws Exception
    */
    public static byte[] decryptByPublicKey(byte[] data, String key)  
    throws Exception {  
    // 对密钥解密  
    byte[] keyBytes = decryptBASE64(key)  
    // 取得公钥  
    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes)  
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)  
    Key publicKey = keyFactory.generatePublic(x509KeySpec)  
    // 对数据解密  
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm())  
    cipher.init(Cipher.DECRYPT_MODE, publicKey)  
    return cipher.doFinal(data)  
    }  
    /** *//**
    * 加密

    * 用公钥加密
    *  
    * @param data
    * @param key
    * @return
    * @throws Exception
    */
    public static byte[] encryptByPublicKey(byte[] data, String key)  
    throws Exception {  
    // 对公钥解密  
    byte[] keyBytes = decryptBASE64(key)  
    // 取得公钥  
    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes)  
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)  
    Key publicKey = keyFactory.generatePublic(x509KeySpec)  
    // 对数据加密  
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm())  
    cipher.init(Cipher.ENCRYPT_MODE, publicKey)  
    return cipher.doFinal(data)  
    }  
    /** *//**
    * 加密

    * 用私钥加密
    *  
    * @param data
    * @param key
    * @return
    * @throws Exception
    */
    public static byte[] encryptByPrivateKey(byte[] data, String key)  
    throws Exception {  
    // 对密钥解密  
    byte[] keyBytes = decryptBASE64(key)  
    // 取得私钥  
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)  
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)  
    Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec)  
    // 对数据加密  
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm())  
    cipher.init(Cipher.ENCRYPT_MODE, privateKey)  
    return cipher.doFinal(data)  
    }  
    /** *//**
    * 取得私钥
    *  
    * @param keyMap
    * @return
    * @throws Exception
    */
    public static String getPrivateKey(Map keyMap)  
    throws Exception {  
    Key key = (Key) keyMap.get(PRIVATE_KEY)  
    return encryptBASE64(key.getEncoded())  
    }  
    /** *//**
    * 取得公钥
    *  
    * @param keyMap
    * @return
    * @throws Exception
    */
    public static String getPublicKey(Map keyMap)  
    throws Exception {  
    Key key = (Key) keyMap.get(PUBLIC_KEY)  
    return encryptBASE64(key.getEncoded())  
    }  
    /** *//**
    * 初始化密钥
    *  
    * @return
    * @throws Exception
    */
    public static Map initKey() 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 keyMap = new HashMap(2)  
    keyMap.put(PUBLIC_KEY, publicKey)  
    keyMap.put(PRIVATE_KEY, privateKey)  
    return keyMap  
    }  
}
再给出一个测试类:
import static org.junit.Assert.*  
import org.junit.Before  
import org.junit.Test  
import java.util.Map  
/** *//**
*  
* @version 1.0
* @since 1.0
*/
public class RSACoderTest {  
    private String publicKey  
    private String privateKey  
    @Before
    public void setUp() throws Exception {  
    Map keyMap = RSACoder.initKey()  
    publicKey = RSACoder.getPublicKey(keyMap)  
    privateKey = RSACoder.getPrivateKey(keyMap)  
    System.err.println("公钥: " publicKey)  
    System.err.println("私钥: " privateKey)  
    }  
    @Test
    public void test() throws Exception {  
    System.err.println("公钥加密——私钥解密")  
    String inputStr = "abc"  
    byte[] data = inputStr.getBytes()  
    byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey)  
    byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,  
    privateKey)  
    String outputStr = new String(decodedData)  
    System.err.println("加密前: " inputStr " " "解密后: " outputStr)  
    assertEquals(inputStr, outputStr)  
    }  
    @Test
    public void testSign() throws Exception {  
    System.err.println("私钥加密——公钥解密")  
    String inputStr = "sign"  
    byte[] data = inputStr.getBytes()  
    byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey)  
    byte[] decodedData = RSACoder  
    .decryptByPublicKey(encodedData, publicKey)  
    String outputStr = new String(decodedData)  
    System.err.println("加密前: " inputStr " " "解密后: " outputStr)  
    assertEquals(inputStr, outputStr)  
    System.err.println("私钥签名——公钥验证签名")  
    // 产生签名  
    String sign = RSACoder.sign(encodedData, privateKey)  
    System.err.println("签名: " sign)  
    // 验证签名  
    boolean status = RSACoder.verify(encodedData, publicKey, sign)  
    System.err.println("状态: " status)  
    assertTrue(status)  
    }  
}
详见: http://yingfang05.javaeye.com/blog/42502

RSA算法 写出加解密过程

没有e没法求d p和q也没给 我郁闷
先说欧几里得算法,这个是一个函数,求的话累死。
欧几里得算法是求最大公约数的,求逆元用扩展的欧几里得算法
原理:
如果gcd(a,b)=d,则存在m,n,使得d = ma nb,称呼这种关系为a、b组合整数d,m,n称为组合系数。当d=1时,有 ma nb = 1 ,此时可以看出m是a模b的乘法逆元,n是b模a的乘法逆元。
int gcd(int a, int b , int&; ar,int &; br)
{
int x1,x2,x3;
int y1,y2,y3;
int t1,t2,t3;
if(0 == a)
{//有一个数为0,就不存在乘法逆元

ar = 0;

br = 0 ;

return b;
}
if(0 == b)
{

ar = 0;

br = 0 ;

return a;
}
x1 = 1;x2 = 0;x3 = a;
y1 = 0;y2 = 1;y3 = b;
int k;
for( t3 = x3 % y3 ; t3 != 0 ; t3 = x3 % y3)
{

k = x3 / y3;t2 = x2 - k * y2;t1 = x1 - k * y1;

x1 = y1;x1 = y2;x3 = y3;

y1 = t1;y2 = t2;y3 = t3;
}
if( y3 == 1)
{ //有乘法逆元

ar = y2;

br = x1;

return 1;
}

else

{ //公约数不为1,无乘法逆元。这个是存在逆元的充要条件

ar = 0;

br = 0;

return y3;
}
}
核心是
for( t3 = x3 % y3 ; t3 != 0 ; t3 = x3 % y3)
{

k = x3 / y3;t2 = x2 - k * y2;t1 = x1 - k * y1;

x1 = y1;x1 = y2;x3 = y3;

y1 = t1;y2 = t2;y3 = t3;
}
一共有三行
x1 ,x2 ,x y1 ,y2 ,y t1 ,t2 ,t 每次循环第三行都是算出来的 然后 把第一行y的值放到x t的值放到y
这三行都满足一个共同的性质
第一个数*a 第二个数*b=第三个数
比如x1*a x2*b=x 每次循环问题都会简化,距离结果更进
直到
当最终t3迭代计算到1时,有t1× a t2 × b = 1,显然,t1是a模b的乘法逆元,t2是b模a的乘法逆元。

生成p,q两个素数,产生方法就是随机产生一个数,然后用素性检验算法判断是不是素数,如果不是再随机产生一个判断。关于素性经验,这个问题很大,是本数论书都有,这里没法展开讲。
比如p=3,q=1 生成n=p*q=3 生成n的欧拉函数 N=(p-1)*(q-1)=20
选取公钥e=3 然后计算d
e*d=1(mod N) e和d是关于模N的互为逆元的关系,用扩展的欧几里得算法
得出来d=7 也就是说3*7=1(mod 20)
加密用e M的每个字母转换成ASCII码 设明文字母为m 密文为c
加密过程:c=m的e次方(mod n) 也就说c=m的三次方(mod 33)
解密过程:m=c的d次方(mod n) 也就是说m=c的7次方(mod 33)

百度知道没有公式编辑器让我很痛苦
注意别把N=(p-1)*(q-1)和n=p*q搞混了 N用于求d n用于加密解密

RSA我熟的很 还做过一个ppt 实现还有简单的一些弱点 本来想发给楼主 但是貌似我换了7-zip后把我以前的压缩包打不开了 也可能损坏了

最新文章