Android 客户端RSA加密的实现方法
程序员文章站
2023-12-15 19:07:22
android 客户端rsa加密的实现方法
针对java后端进行的rsa加密,android客户端进行解密,结果是部分乱码的问题:
注意两点,编码问题和客户端使用的...
android 客户端rsa加密的实现方法
针对java后端进行的rsa加密,android客户端进行解密,结果是部分乱码的问题:
注意两点,编码问题和客户端使用的算法问题
即:都使用utf-8编码,base64使用一致,另外,使用下面的代码在后端和移动端解密只有一点不同:
移动端使用
cipher cipher = cipher.getinstance("rsa/ecb/pkcs1padding");
后端使用
cipher cipher = cipher.getinstance("rsa");
其他地方都不需要改动
package rsa; import android.util.base64; import java.io.bytearrayinputstream; import java.io.bytearrayoutputstream; import java.io.file; import java.io.fileinputstream; import java.io.fileoutputstream; import java.io.inputstream; import java.io.outputstream; //import org.apache.commons.codec.binary.base64; /** *//** * <p> * base64编码解码工具包 * </p> * @author icewee * @date 2012-5-19 * @version 1.0 */ public class base64utils { /** *//** * 文件读取缓冲区大小 */ private static final int cache_size = 1024; /** *//** * <p> * base64字符串解码为二进制数据 * </p> * * @param base64 * @return * @throws exception */ public static byte[] decode(string base64) throws exception { return base64.decode(base64.getbytes(), base64.default); } /** *//** * <p> * 二进制数据编码为base64字符串 * </p> * * @param bytes * @return * @throws exception */ public static string encode(byte[] bytes) throws exception { return new string(base64.encode(bytes, base64.default)); } /** * * @param str * @return * @throws exception */ public static string encode(string str) throws exception { byte[] bytes = str.getbytes("utf-8"); return encode(bytes); } /** *//** * <p> * 将文件编码为base64字符串 * </p> * <p> * 大文件慎用,可能会导致内存溢出 * </p> * * @param filepath 文件绝对路径 * @return * @throws exception */ public static string encodefile(string filepath) throws exception { byte[] bytes = filetobyte(filepath); return encode(bytes); } /** *//** * <p> * base64字符串转回文件 * </p> * * @param filepath 文件绝对路径 * @param base64 编码字符串 * @throws exception */ public static void decodetofile(string filepath, string base64) throws exception { byte[] bytes = decode(base64); bytearraytofile(bytes, filepath); } /** *//** * <p> * 文件转换为二进制数组 * </p> * * @param filepath 文件路径 * @return * @throws exception */ public static byte[] filetobyte(string filepath) throws exception { byte[] data = new byte[0]; file file = new file(filepath); if (file.exists()) { fileinputstream in = new fileinputstream(file); bytearrayoutputstream out = new bytearrayoutputstream(2048); byte[] cache = new byte[cache_size]; int nread = 0; while ((nread = in.read(cache)) != -1) { out.write(cache, 0, nread); out.flush(); } out.close(); in.close(); data = out.tobytearray(); } return data; } /** *//** * <p> * 二进制数据写文件 * </p> * * @param bytes 二进制数据 * @param filepath 文件生成目录 */ public static void bytearraytofile(byte[] bytes, string filepath) throws exception { inputstream in = new bytearrayinputstream(bytes); file destfile = new file(filepath); if (!destfile.getparentfile().exists()) { destfile.getparentfile().mkdirs(); } destfile.createnewfile(); outputstream out = new fileoutputstream(destfile); byte[] cache = new byte[cache_size]; int nread = 0; while ((nread = in.read(cache)) != -1) { out.write(cache, 0, nread); out.flush(); } out.close(); in.close(); } }
package rsa; import android.util.base64; import java.io.bytearrayoutputstream; 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; /** * <p> * rsa公钥/私钥/签名工具包 * </p> * <p> * 罗纳德·李维斯特(ron [r]ivest)、阿迪·萨莫尔(adi [s]hamir)和伦纳德·阿德曼(leonard [a]dleman) * </p> * <p> * 字符串格式的密钥在未在特殊说明情况下都为base64编码格式<br/> * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/> * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全 * </p> * * @author icewee * @date 2012-4-26 * @version 1.0 */ public class rsautils { /** * 加密算法rsa */ public static final string key_algorithm = "rsa"; /** * 签名算法 */ public static final string signature_algorithm = "md5withrsa"; /** * 获取公钥的key */ private static final string public_key = "rsapublickey"; /** * 获取私钥的key */ private static final string private_key = "rsaprivatekey"; /** * rsa最大加密明文大小 */ private static final int max_encrypt_block = 117; /** * rsa最大解密密文大小 */ private static final int max_decrypt_block = 128; /** * <p> * 生成密钥对(公钥和私钥) * </p> * * @return * @throws exception */ public static map<string, object> genkeypair() 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<string, object> keymap = new hashmap<string, object>(2); keymap.put(public_key, publickey); keymap.put(private_key, privatekey); return keymap; } /** * <p> * 用私钥对信息生成数字签名 * </p> * * @param data 已加密数据 * @param privatekey 私钥(base64编码) * * @return * @throws exception */ public static string sign(byte[] data, string privatekey) throws exception { byte[] keybytes = base64.decode(privatekey,0); pkcs8encodedkeyspec pkcs8keyspec = new pkcs8encodedkeyspec(keybytes); keyfactory keyfactory = keyfactory.getinstance(key_algorithm); privatekey privatek = keyfactory.generateprivate(pkcs8keyspec); signature signature = signature.getinstance(signature_algorithm); signature.initsign(privatek); signature.update(data); return base64.encodetostring(signature.sign(), 0); } /** * <p> * 校验数字签名 * </p> * * @param data 已加密数据 * @param publickey 公钥(base64编码) * @param sign 数字签名 * * @return * @throws exception * */ public static boolean verify(byte[] data, string publickey, string sign) throws exception { byte[] keybytes = base64.decode(publickey,0); x509encodedkeyspec keyspec = new x509encodedkeyspec(keybytes); keyfactory keyfactory = keyfactory.getinstance(key_algorithm); publickey publick = keyfactory.generatepublic(keyspec); signature signature = signature.getinstance(signature_algorithm); signature.initverify(publick); signature.update(data); return signature.verify(base64.decode(sign,0)); } /** * <p> * 私钥解密 * </p> * * @param encrypteddata 已加密数据 * @param privatekey 私钥(base64编码) * @return * @throws exception */ public static byte[] decryptbyprivatekey(byte[] encrypteddata, string privatekey) throws exception { byte[] keybytes = base64.decode(privatekey, 0); pkcs8encodedkeyspec pkcs8keyspec = new pkcs8encodedkeyspec(keybytes); keyfactory keyfactory = keyfactory.getinstance(key_algorithm); key privatek = keyfactory.generateprivate(pkcs8keyspec); cipher cipher = cipher.getinstance("rsa/ecb/pkcs1padding"); cipher.init(cipher.decrypt_mode, privatek); 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; } /** * <p> * 公钥解密 * </p> * * @param encrypteddata 已加密数据 * @param publickey 公钥(base64编码) * @return * @throws exception */ public static byte[] decryptbypublickey(byte[] encrypteddata, string publickey) throws exception { byte[] keybytes = base64.decode(publickey,0); x509encodedkeyspec x509keyspec = new x509encodedkeyspec(keybytes); keyfactory keyfactory = keyfactory.getinstance(key_algorithm); key publick = keyfactory.generatepublic(x509keyspec); cipher cipher = cipher.getinstance(keyfactory.getalgorithm()); cipher.init(cipher.decrypt_mode, publick); 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; } /** * <p> * 公钥加密 * </p> * * @param data 源数据 * @param publickey 公钥(base64编码) * @return * @throws exception */ public static byte[] encryptbypublickey(byte[] data, string publickey) throws exception { byte[] keybytes = base64.decode(publickey,0); x509encodedkeyspec x509keyspec = new x509encodedkeyspec(keybytes); keyfactory keyfactory = keyfactory.getinstance(key_algorithm); key publick = keyfactory.generatepublic(x509keyspec); // 对数据加密 cipher cipher = cipher.getinstance(keyfactory.getalgorithm()); cipher.init(cipher.encrypt_mode, publick); 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[] encrypteddata = out.tobytearray(); out.close(); return encrypteddata; } /** * <p> * 私钥加密 * </p> * * @param data 源数据 * @param privatekey 私钥(base64编码) * @return * @throws exception */ public static byte[] encryptbyprivatekey(byte[] data, string privatekey) throws exception { byte[] keybytes = base64.decode(privatekey,0); pkcs8encodedkeyspec pkcs8keyspec = new pkcs8encodedkeyspec(keybytes); keyfactory keyfactory = keyfactory.getinstance(key_algorithm); key privatek = keyfactory.generateprivate(pkcs8keyspec); cipher cipher = cipher.getinstance(keyfactory.getalgorithm()); cipher.init(cipher.encrypt_mode, privatek); 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[] encrypteddata = out.tobytearray(); out.close(); return encrypteddata; } /** * <p> * 获取私钥 * </p> * * @param keymap 密钥对 * @return * @throws exception */ public static string getprivatekey(map<string, object> keymap) throws exception { key key = (key) keymap.get(private_key); return base64.encodetostring(key.getencoded(),0); } /** * <p> * 获取公钥 * </p> * * @param keymap 密钥对 * @return * @throws exception */ public static string getpublickey(map<string, object> keymap) throws exception { key key = (key) keymap.get(public_key); return base64.encodetostring(key.getencoded(), 0); } }
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!