java

位置:IT落伍者 >> java >> 浏览文章

java非对称加密的源代码(RSA)


发布日期:2020年06月03日
 
java非对称加密的源代码(RSA)

鑒于rsa加密的重要性和相关源代码的匮乏经过整理特此贴出需要下载bcprovjdkjar

import javaxcryptoCipher;

import javasecurity*;

import javasecurityspecRSAPublicKeySpec;

import javasecurityspecRSAPrivateKeySpec;

import javasecurityspecInvalidKeySpecException;

import javasecurityinterfacesRSAPrivateKey;

import javasecurityinterfacesRSAPublicKey;

import javaio*;

import javamathBigInteger;

/**

* RSA 工具类提供加密解密生成密钥对等方法

* 需要到下载bcprovjdkjar

*

*/

public class RSAUtil {

/**

* 生成密钥对

* @return KeyPair

* @throws EncryptException

*/

public static KeyPair generateKeyPair() throws EncryptException {

try {

KeyPairGenerator keyPairGen = KeyPairGeneratorgetInstance(RSA

new orgbouncycastlejceproviderBouncyCastleProvider());

final int KEY_SIZE = ;//没什么好说的了这个值关系到块加密的大小可以更改但是不要太大否则效率会低

keyPairGeninitialize(KEY_SIZE new SecureRandom());

KeyPair keyPair = keyPairGengenKeyPair();

return keyPair;

} catch (Exception e) {

throw new EncryptException(egetMessage());

}

}

/**

* 生成公钥

* @param modulus

* @param publicExponent

* @return RSAPublicKey

* @throws EncryptException

*/

public static RSAPublicKey generateRSAPublicKey(byte[] modulus byte[] publicExponent) throws EncryptException {

KeyFactory keyFac = null;

try {

keyFac = KeyFactorygetInstance(RSA new orgbouncycastlejceproviderBouncyCastleProvider());

} catch (NoSuchAlgorithmException ex) {

throw new EncryptException(exgetMessage());

}

RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus) new BigInteger(publicExponent));

try {

return (RSAPublicKey) keyFacgeneratePublic(pubKeySpec);

} catch (InvalidKeySpecException ex) {

throw new EncryptException(exgetMessage());

}

}

/**

* 生成私钥

* @param modulus

* @param privateExponent

* @return RSAPrivateKey

* @throws EncryptException

*/

public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus byte[] privateExponent) throws EncryptException {

KeyFactory keyFac = null;

try {

keyFac = KeyFactorygetInstance(RSA new orgbouncycastlejceproviderBouncyCastleProvider());

} catch (NoSuchAlgorithmException ex) {

throw new EncryptException(exgetMessage());

}

RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus) new BigInteger(privateExponent));

try {

return (RSAPrivateKey) keyFacgeneratePrivate(priKeySpec);

} catch (InvalidKeySpecException ex) {

throw new EncryptException(exgetMessage());

}

}

/**

* 加密

* @param key 加密的密钥

* @param data 待加密的明文数据

* @return 加密后的数据

* @throws EncryptException

*/

public static byte[] encrypt(Key key byte[] data) throws EncryptException {

try {

Cipher cipher = CiphergetInstance(RSA new orgbouncycastlejceproviderBouncyCastleProvider());

cipherinit(CipherENCRYPT_MODE key);

int blockSize = ciphergetBlockSize();//获得加密块大小加密前数据为个byte而key_size= 加密块大小为 byte加密后为个byte;因此共有个加密块第一个 byte第二个为个byte

int outputSize = ciphergetOutputSize(datalength);//获得加密块加密后块大小

int leavedSize = datalength % blockSize;

int blocksSize = leavedSize != ? datalength / blockSize + : datalength / blockSize;

byte[] raw = new byte[outputSize * blocksSize];

int i = ;

while (datalength i * blockSize > ) {

if (datalength i * blockSize > blockSize)

cipherdoFinal(data i * blockSize blockSize raw i * outputSize);

else

cipherdoFinal(data i * blockSize datalength i * blockSize raw i * outputSize);

//这里面doUpdate方法不可用查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中而最后doFinal的时候才将所有的byte[]进行加密可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法

i++;

}

return raw;

} catch (Exception e) {

throw new EncryptException(egetMessage());

}

}

/**

* 解密

* @param key 解密的密钥

* @param raw 已经加密的数据

* @return 解密后的明文

* @throws EncryptException

*/

public static byte[] decrypt(Key key byte[] raw) throws EncryptException {

try {

Cipher cipher = CiphergetInstance(RSA new orgbouncycastlejceproviderBouncyCastleProvider());

cipherinit(cipherDECRYPT_MODE key);

int blockSize = ciphergetBlockSize();

ByteArrayOutputStream bout = new ByteArrayOutputStream();

int j = ;

while (rawlength j * blockSize > ) {

boutwrite(cipherdoFinal(raw j * blockSize blockSize));

j++;

}

return bouttoByteArray();

} catch (Exception e) {

throw new EncryptException(egetMessage());

}

}

/**

*

* @param args

* @throws Exception

*/

public static void main(String[] args) throws Exception {

File file = new File(l);

FileInputStream in = new FileInputStream(file);

ByteArrayOutputStream bout = new ByteArrayOutputStream();

byte[] tmpbuf = new byte[];

int count = ;

while ((count = inread(tmpbuf)) != ) {

boutwrite(tmpbuf count);

tmpbuf = new byte[];

}

inclose();

byte[] orgData = bouttoByteArray();

KeyPair keyPair = RSAUtilgenerateKeyPair();

RSAPublicKey pubKey = (RSAPublicKey) keyPairgetPublic();

RSAPrivateKey priKey = (RSAPrivateKey) keyPairgetPrivate();

byte[] pubModBytes = pubKeygetModulus()toByteArray();

byte[] pubPubExpBytes = pubKeygetPublicExponent()toByteArray();

byte[] priModBytes = priKeygetModulus()toByteArray();

byte[] priPriExpBytes = priKeygetPrivateExponent()toByteArray();

RSAPublicKey recoveryPubKey = RSAUtilgenerateRSAPublicKey(pubModBytespubPubExpBytes);

RSAPrivateKey recoveryPriKey = RSAUtilgenerateRSAPrivateKey(priModBytespriPriExpBytes);

byte[] raw = RSAUtilencrypt(priKey orgData);

file = new File(encrypt_resultdat);

OutputStream out = new FileOutputStream(file);

outwrite(raw);

outclose();

byte[] data = RSAUtildecrypt(recoveryPubKey raw);

file = new File(l);

out = new FileOutputStream(file);

outwrite(data);

outflush();

outclose();

}

}

加密可以用公钥解密用私钥或者加密用私钥通常非对称加密是非常消耗资源的因此可以对大数据用对称加密如des(具体代码可以看我以前发的贴子)而对其对称密钥进行非对称加密这样既保证了数据的安全还能保证效率               

上一篇:Java I/O API之性能分析 (上)

下一篇:Java设计模式之Command 模式