Keep on going, never give up.

Java RSA加密解密实现

Java里关于算法方法的库有太多、太杂,本来理论只有一种,为方便开发,也应压缩公共库的种类和规模,算法库太多只会给开发者带来负担,这是题外话,本文说说RSA的Java实现,因为效率关系,使用Java库来实现的加密解密并不适合在实时性要求太高的场合。但做普通的用途绰绰有余,比如验证用户帐号、异步加密解密等等。

这是我早前写的部分程序,包含RSA设置公钥、私钥,读取RSA公钥、私钥。更多阅读:

Java DES加解密Java AES加解密

AES CBC和CTR加解密实例

AES CFB/OFB/ECB/CBC/CTR优缺点

一、使用RSA标准库加密解密

涉及导入引用文件(根据需要增减):

import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

RSA加密和解密程序,使用时注意RSA的工作模式,本程序默认ECB/PCKS1Padding,这个模式需要在项目中统一。

private Cipher               cObj;
private SecretKeySpec     sAesKey;
private SecretKey          sDesPwd;
private IvParameterSpec ivDesIps;
private SecureRandom sr = new SecureRandom(); 

private RSAPrivateKey     privateKey;  
private RSAPublicKey     publicKey;

public void RSAInit()  throws Exception{
        cObj = Cipher.getInstance("RSA/ECB/PKCS1Padding");//NoPadding PKCS5Padding
    }
    
    public void genKeyPair() throws Exception{  
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");  
        //SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
        keyPairGen.initialize(1024, new SecureRandom());
        KeyPair keyPair= keyPairGen.generateKeyPair();
        privateKey= (RSAPrivateKey) keyPair.getPrivate();  
        publicKey= (RSAPublicKey) keyPair.getPublic();
     }
    
    public byte[] getRSAPubKey(){//Attension: ASN.1 objects will be returned
        byte[] btRecv = publicKey.getEncoded();
        return btRecv;
    }
 
    public byte[] getRSAPriKey(){//Attension: ASN.1 objects will be returned
        byte[] btRecv = privateKey.getEncoded();
        return btRecv;
    }
    
    public boolean setRSAPubKey(byte[] btRecv) throws Exception{
        publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(btRecv));
        return true;
    }
    public boolean setRSAPriKey(byte[] btRecv) throws Exception{
        privateKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new X509EncodedKeySpec(btRecv));
        return true;
    }
    
    public byte[] RSAEncode(byte[] btCont)  throws Exception{
         cObj.init(Cipher.ENCRYPT_MODE, publicKey);
        return cObj.doFinal(btCont);
    }   
        
    public byte[] RSADecode(byte[] btCont) throws Exception{
        cObj.init(Cipher.DECRYPT_MODE, privateKey);
        return cObj.doFinal(btCont);
    }

二、直接使用RSA大数运算

了解RSA算法的读者,也可直接使用大数运算库,进行模运算计算出RSA结果,加密示例如下:

String en=HexToString(publicKey.getEncoded(),publicKey.getEncoded().length);
BigInteger n = new BigInteger(en.substring(0,256),16);
BigInteger e = new BigInteger(en.substring(256),16);
String c=HexToString(btCont,128);
BigInteger biText = new BigInteger(c,16);
//BigInteger biText = new BigInteger(cont);
BigInteger biEnText = biText.modPow(e, n);
byte[] btRecv = biEnText.toByteArray();

其中,btCont为需要加密的内容,HexToString就是把Hex十六进制数输出为字符串,比如:0x1234,则输出为1234字符串,不再贴出源码。

解密部分可对应RSA算法进行相应修改即可。

相关评论(0):  

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

订阅博客

最新文章

本站采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载也必须遵循“署名-非商业用途-保持一致”的创作共用协议. 返回顶部
Copyright@2005-2016 Metsky.com, All rights Reserved.