RSA 非对称加密算法的Java实现
程序员文章站
2022-07-09 21:13:47
关于RSA的介绍Google一下很多,这里不做说明。项目开发中一般会把公钥放在本地进行加密,服务端通过私钥进行解密。Android项目开发中要用到这个加密算法,总结后实现如下: 使用如下: ......
关于rsa的介绍google一下很多,这里不做说明。项目开发中一般会把公钥放在本地进行加密,服务端通过私钥进行解密。android项目开发中要用到这个加密算法,总结后实现如下:
import android.content.context; import android.util.base64; import java.io.bufferedreader; import java.io.ioexception; import java.io.inputstream; import java.io.inputstreamreader; import java.security.key; import java.security.keyfactory; import java.security.nosuchalgorithmexception; import java.security.privatekey; import java.security.publickey; import java.security.spec.invalidkeyspecexception; import java.security.spec.pkcs8encodedkeyspec; import java.security.spec.x509encodedkeyspec; import javax.crypto.cipher; public class rsautil { /** * key_algorithm */ public static final string key_algorithm = "rsa"; /** * 加密key的长度等于1024 */ public static int keysize = 1024; /** * 解密时必须按照此分组解密 */ public static int decodelen = keysize / 8; /** * 加密时小于117即可 */ public static int encodelen = 110;//(default_key_size / 8) - 11; /** * 加密填充方式,android系统的rsa实现是"rsa/none/nopadding",而标准jdk实现是"rsa/none/pkcs1padding" ,这造成了在android机上加密后无法在服务器上解密的原因 */ public static final string ecb_pkcs1_padding = "rsa/ecb/pkcs1padding"; public static final byte[] empty_byte_array = new byte[0]; /** * 通过公钥加密 */ public static byte[] encryptpublickey(byte[] encrypteddata, string key) throws exception { if (encrypteddata == null) { throw new illegalargumentexception("input encryption data is null"); } byte[] encode = new byte[]{}; for (int i = 0; i < encrypteddata.length; i += encodelen) { byte[] subarray = subarray(encrypteddata, i, i + encodelen); byte[] dofinal = encryptbypublickey(subarray, key); encode = addall(encode, dofinal); } return encode; } /** * 通过私钥解密 */ public static byte[] decryptprivatekey(byte[] encode, string key) throws exception { if (encode == null) { throw new illegalargumentexception("input data is null"); } byte[] buffers = new byte[]{}; for (int i = 0; i < encode.length; i += decodelen) { byte[] subarray = subarray(encode, i, i + decodelen); byte[] dofinal = decryptbyprivatekey(subarray, key); buffers = addall(buffers, dofinal); } return buffers; } /** * 从字符串中加载公钥 * * @param publickeystr 公钥数据字符串 */ private static publickey loadpublickey(string publickeystr) throws exception { try { byte[] buffer = decode(publickeystr); keyfactory keyfactory = keyfactory.getinstance(key_algorithm); //表示根据 asn.1 类型 subjectpublickeyinfo 进行编码的公用密钥的 asn.1 编码。 x509encodedkeyspec keyspec = new x509encodedkeyspec(buffer); return 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指令)。 */ private static privatekey loadprivatekey(string privatekeystr) throws exception { try { byte[] buffer = decode(privatekeystr); //表示按照 asn.1 类型 privatekeyinfo 进行编码的专用密钥的 asn.1 编码。 pkcs8encodedkeyspec keyspec = new pkcs8encodedkeyspec(buffer); keyfactory keyfactory = keyfactory.getinstance(key_algorithm); return keyfactory.generateprivate(keyspec); } catch (nosuchalgorithmexception e) { throw new exception("无此算法"); } catch (invalidkeyspecexception e) { throw new exception("私钥非法"); } catch (nullpointerexception e) { throw new exception("私钥数据为空"); } } /** * 用私钥解密 */ private static byte[] decryptbyprivatekey(byte[] data, string key) throws exception { if (data == null) { throw new illegalargumentexception("input data is null"); } //取得私钥 key privatekey = loadprivatekey(key); // 对数据解密 cipher cipher = cipher.getinstance(ecb_pkcs1_padding); cipher.init(cipher.decrypt_mode, privatekey); return cipher.dofinal(data); } /** * 用公钥加密 */ private static byte[] encryptbypublickey(byte[] data, string key) throws exception { if (data == null) { throw new illegalargumentexception("input data is null"); } // 取得公钥 key publickey = loadpublickey(key); // 对数据加密 cipher cipher = cipher.getinstance(ecb_pkcs1_padding); cipher.init(cipher.encrypt_mode, publickey); return cipher.dofinal(data); } /** * <p> * base64字符串解码为二进制数据 * </p> */ public static byte[] decode(string base64) { return base64.decode(base64, base64.default); } /** * <p> * 二进制数据编码为base64字符串 * </p> */ public static string encode(byte[] bytes) { return base64.encodetostring(bytes, base64.default); } /** * <p>produces a new {@code byte} array containing the elements * between the start and end indices. * * <p>the start index is inclusive, the end index exclusive. * null array input produces null output. * * @param array the array * @param startindexinclusive the starting index. undervalue (<0) * is promoted to 0, overvalue (>array.length) results * in an empty array. * @param endindexexclusive elements up to endindex-1 are present in the * returned subarray. undervalue (< startindex) produces * empty array, overvalue (>array.length) is demoted to * array length. * @return a new array containing the elements between * the start and end indices. * @since 2.1 */ private static byte[] subarray(final byte[] array, int startindexinclusive, int endindexexclusive) { if (array == null) { return null; } if (startindexinclusive < 0) { startindexinclusive = 0; } if (endindexexclusive > array.length) { endindexexclusive = array.length; } final int newsize = endindexexclusive - startindexinclusive; if (newsize <= 0) { return empty_byte_array; } final byte[] subarray = new byte[newsize]; system.arraycopy(array, startindexinclusive, subarray, 0, newsize); return subarray; } /** * <p>adds all the elements of the given arrays into a new array. * <p>the new array contains all of the element of {@code array1} followed * by all of the elements {@code array2}. when an array is returned, it is always * a new array. * * @param array1 the first array whose elements are added to the new array. * @param array2 the second array whose elements are added to the new array. * @return the new byte[] array. * @since 2.1 */ private static byte[] addall(final byte[] array1, final byte... array2) { if (array1 == null) { return clone(array2); } else if (array2 == null) { return clone(array1); } final byte[] joinedarray = new byte[array1.length + array2.length]; system.arraycopy(array1, 0, joinedarray, 0, array1.length); system.arraycopy(array2, 0, joinedarray, array1.length, array2.length); return joinedarray; } /** * <p>clones an array returning a typecast result and handling * {@code null}. * * <p>this method returns {@code null} for a {@code null} input array. * * @param array the array to clone, may be {@code null} * @return the cloned array, {@code null} if {@code null} input */ private static byte[] clone(final byte[] array) { if (array == null) { return null; } return array.clone(); } /** * 读取密钥信息 */ public static string readstring(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 encryptstr 待加密字符串 * rsa_public_key.pem 为本地公钥 */ public string getencryptdata(context context, string encryptstr) { try { inputstream inpublic = context.getresources().getassets().open("rsa_public_key.pem"); string publickey = readstring(inpublic); byte[] encodeddata = encryptpublickey(encryptstr.getbytes(), publickey); return encode(encodeddata); } catch (ioexception e) { e.printstacktrace(); } catch (exception e) { e.printstacktrace(); } return ""; }
上一篇: 关于H5的一些相关基础知识