iOS开发 RSA加密解密与后台之间的双向加密详解
转载自:https://www.jianshu.com/p/43f7fc8d8e14
序言
因为项目中需要用到RSA
加密,刚开始也是有点乱,这两天也整理的差不多了,希望能帮到大家。这次先上代码,我想大部分人肯定是着急解决问题,所以不要废话太多。
iOS端
后台是PHP
,给我了一段公钥和他用私钥加密后的base64
编码,让我先解一下,看看能否解出(请先不要纠结为什么给我公钥解密,公钥私钥都可以解密,具体后面会讲到)。公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3//sR2tXw0wrC2DySx8vNGlqt
3Y7ldU9+LBLI6e1KS5lfc5jlTGF7KBTSkCHBM3ouEHWqp1ZJ85iJe59aF5gIB2kl
Bd6h4wrbbHA2XE1sq21ykja/Gqx7/IRia3zQfxGv/qEkyGOx+XALVoOlZqDwh76o
2n1vP1D+tD3amHsK7QIDAQAB
base64编码后的加密数据(注意:后台给你的一定是经过base64编码后的):
eZVIkIEDb83YfdpOQCTg1SMfJtAHjdl92oKCALYeItxwvvyBsIR/L2e7y1+rXYCztBELXff/L9SijAYrUWOcvPVLPlkJbiJhZjRn+v4L9UeLtSUfO/qv30K3JROb2OniOvRImK3ZcBq319VT8e62zjJscGBIlwfFfMxRVT/mAzY=
下面使用RSA这是一个封装的第三方框架,只需要将下面这两个文件导入到项目中,便可以使用(不用再导入其他的一些框架),别的框架不敢保证能使用,但这个是肯定可以使用的。
代码:
//公钥NSString *publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3//sR2tXw0wrC2DySx8vNGlqt3Y7ldU9+LBLI6e1KS5lfc5jlTGF7KBTSkCHBM3ouEHWqp1ZJ85iJe59aF5gIB2klBd6h4wrbbHA2XE1sq21ykja/Gqx7/IRia3zQfxGv/qEkyGOx+XALVoOlZqDwh76o2n1vP1D+tD3amHsK7QIDAQAB";//base64编码后的加密数据NSString *base64Str = @"eZVIkIEDb83YfdpOQCTg1SMfJtAHjdl92oKCALYeItxwvvyBsIR/L2e7y1+rXYCztBELXff/L9SijAYrUWOcvPVLPlkJbiJhZjRn+v4L9UeLtSUfO/qv30K3JROb2OniOvRImK3ZcBq319VT8e62zjJscGBIlwfFfMxRVT/mAzY=";//结果:注意,这里是用公钥进行解密的,方法一定要用对NSString *resultStr = [RSA decryptString:base64Str publicKey:publicKey];NSLog(@"结果 = %@",resultStr);
打印结果:
这只是先进行测试的数据,如果给你私钥解密,就用别的方法,在RSA.h
中可以很容易找到。
上面讲述的是单向加密,那么如何进行双向加密呢?
- 1、
iOS
端和后台(这里后台使用的是java,因为我后台语言只会java
,效果都是一样的)各生成自己的公钥和私钥。 - 2、
iOS
端生成的公钥和私钥定义为iOSPublicKey
、iOSPrivateKey
,java
端生成的公钥私钥定义为javaPublicKey
、javaPrivateKey
。将iOSPublicKey
给java
,让它用iOSPublicKey
加密数据传给iOS
端,iOS
端用iOSPrivateKey
解密;java
端将javaPublicKey
给iOS
端,iOS
端用javaPublicKey
加密数据后上传给java
,java
端利用javaPrivateKey
去解密,这样就实现了数据传输过程中的加密与解密,当然,也不一定非要按照我上面的步骤来,具体情况要和后台商量如何加密。
具体实现:
iOS端
- 生成公钥和私钥
1)新建文件夹,用来保存生成的私钥和公钥,打开终端 cd 新建
,进入到新建文件夹中,openssl
,打开openssl
genrsa -out rsa_private_key.pem 1024
生成私钥
pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
这步一定要有,需要将私钥转成PKCS8的格式才能使用,此时复制私钥(先复制私钥,然后在4步取出公钥)
4)rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
生成公钥
此时在新建文件夹中会出现两个文件
我们用文本编辑器打开便可获取iOS
端生成的公钥和私钥。
- Xcode项目实战
还得利用上面提到的RSA文件
//公钥NSString *publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDl5RBHD3abOyeYCOLkaWkpJXgJQfMklOWPmdJAnG1eD6CV+UOpUKMy5LtfGHQEM7ao5x3BpMx4MNRUYVwBAmU84PhwNm6xpTJrg5zZCloFmsX+E5ukWE5YFRu8i5+5d8LuQTTTv4XfzbTCTOhON8uj+ypkomETuVNwgRFVFjHd1QIDAQAB";//私钥NSString *privateKey = @"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOXlEEcPdps7J5gI4uRpaSkleAlB8ySU5Y+Z0kCcbV4PoJX5Q6lQozLku18YdAQztqjnHcGkzHgw1FRhXAECZTzg+HA2brGlMmuDnNkKWgWaxf4Tm6RYTlgVG7yLn7l3wu5BNNO/hd/NtMJM6E43y6P7KmSiYRO5U3CBEVUWMd3VAgMBAAECgYEAkqHVDQ4O35oOegmI9plJauYsNvNqqzWRalN5aJ6dn3YmPiI8Bt2ZClgcLt6A+UEmy3qGX0HG7Q5wD9X9geNOQB3ZiD/pGAGW08wS/wTxnWSnSBwdtZ03pUttfnFctkxULfDq4iG1ywdjqEk3F8QVFajQ0c76kWbt9LGAv2OGIi0CQQD2CmbVFXy4JeNHK3TDoLMjsUCiLa+qPnyyVDLDG9Ozb7wN2ydTrMhI+0udmjKvy/Lm1E2bKyp42iYuubEqvSAXAkEA7zNZsOgUe0q73sxXqrLQ7Fs7TNtIEXghrGmkVTHN0I7uMKzQ7KEbA6hfcBm4hPMoLa6Ag3m9tiMNBWtDWc/Y8wJAK0//dEl5EC3TSccTohCbGJBukV47i1u+teHuobw3U2I7F7FZxfgntflPAWqQu7PKieob01IRAv9cM2OLFbv/dwJBAIniXedeQMA5ekaaIEbjwQ8eH/bTyJ1ZVH/gfbwmc2+vlJo2ZFCjJcFcA3fJO9ZXnGeI2cfwG22sksr24+IXsAUCQG5yvVIleTDYqWuWVG1Rc8fk5UFjoZzJpp0nil0z+0fR5rogr4fxcH7vbWsE0id7gSvtV7KxPzkvJTpOK3yGDN0=";//测试要加密的数据NSString *sourceStr = @"iOS端RSA";//公钥加密NSString *encryptStr = [RSA encryptString:sourceStr publicKey:publicKey];//私钥解密NSString *decrypeStr = [RSA decryptString:encryptStr privateKey:privateKey];NSLog(@"加密后的数据 %@ 解密后的数据 %@",encryptStr,decrypeStr);
打印结果:
经过测试,私钥和公钥是可以使用的。
Java端
我是用的是Eclipse
,具体实现方法也是从网上找的,因为打开的东西太多,忘了是哪篇博客了,知道的请联系我,会注明作者的。
- 前期准备
RSAUtils.java
代码:
package RSA;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 = Base64Utils.decode(privateKey); 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 Base64Utils.encode(signature.sign()); } /** *//** * <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 = Base64Utils.decode(publicKey); 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(Base64Utils.decode(sign)); } /** *//** * <P> * 私钥解密 * </p> * * @param encryptedData 已加密数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); 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.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 = Base64Utils.decode(publicKey); 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 = Base64Utils.decode(publicKey); 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 = Base64Utils.decode(privateKey); 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 Base64Utils.encode(key.getEncoded()); } /** *//** * <p> * 获取公钥 * </p> * * @param keyMap 密钥对 xs* @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return Base64Utils.encode(key.getEncoded()); }
}
Base64Utils.java
文件代码:
package RSA;
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 it.sauronsoftware.base64.Base64; 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()); } /** *//** * <p> * 二进制数据编码为BASE64字符串 * </p> * * @param bytes * @return * @throws Exception */ public static String encode(byte[] bytes) throws Exception { return new String(Base64.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(); }}
Test.java
文件中
package RSA;
import java.util.Map; public class Test {static String publicKey; static String privateKey; static { try { Map<String, Object> keyMap = RSAUtils.genKeyPair(); publicKey = RSAUtils.getPublicKey(keyMap); privateKey = RSAUtils.getPrivateKey(keyMap); System.err.println("公钥: \n\r" + publicKey); System.err.println("私钥: \n\r" + privateKey); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception {test();}
//加密数据static void test() throws Exception { String source = "Java端RSA"; System.out.println("\r加密前文字:\r\n" + source); byte[] data = source.getBytes(); byte[] encodedData = RSAUtils.encryptByPrivateKey(data,privateKey); System.out.println("加密后文字:\r\n" + new String(encodedData)); byte[] decodedData = RSAUtils.decryptByPublicKey(encodedData, publicKey); String target = new String(decodedData); System.out.println("解密后文字: \r\n" + target); } //验证签名static void testSign() throws Exception { System.err.println("私钥加密——公钥解密"); String source = "这是一行测试RSA数字签名的无意义文字"; System.out.println("原文字:\r\n" + source); byte[] data = source.getBytes(); byte[] encodedData = RSAUtils.encryptByPrivateKey(data, privateKey); System.out.println("加密后:\r\n" + new String(encodedData)); byte[] decodedData = RSAUtils.decryptByPublicKey(encodedData, publicKey); String target = new String(decodedData); System.out.println("解密后: \r\n" + target); System.err.println("私钥签名——公钥验证签名"); String sign = RSAUtils.sign(encodedData, privateKey); System.err.println("签名:\r" + sign); boolean status = RSAUtils.verify(encodedData, publicKey, sign); System.err.println("验证结果:\r" + status); }
}
打印结果:
在此,我们可以获取java端生成的私钥和公钥
javaPrivateKey
:
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAICJzSMJQJWRMP/eAQpHpeFvoZ6TlEpDwzOu7U7COK0QFOfbSqw8+jVckcUXsbIeluay5kQBogrlzcBcEOUabMczFQRsb9Lo9fa1TObDPOb+Vexg2ndk6BjGO85npXTQlRx1PQzJ2JoFWjdwFxUX9bgkeZLgkYyPpQroHK4SIe5HAgMBAAECgYAYl8T67htAQp5IZjZ2vAyd3Fjk2UGnD936Nn7K8dgcLJaDYe6gk64fpY1yUz05YibnDtWFr3ZMdXlvU24cF3k2PoIyu/CK+/HxToAI1kx0yk52QdiBfiG9vPIqZmCCDWYm0kLE1ayEt2JMDbMWqlMfA7LWzlFEPsO63Jc4hH0BOQJBAPul4inORuoDgtBPxPGUcCICJJZ0xw+kFxgZjSnV0qcP3nQDdzqLiPPJ9Z8jJziIUEqXaxI0qOG7OFlMW8os5qUCQQCCwuBk/Gve/z+j386yiaJFQwxH8SAO97FuHDmYPJtdjrX7o6Uboq9GydzrPwNNK1odV4S858pXksZnU7K2lRl7AkEA6cv8i4qyJ8iLSK5T835Nj8sd4wsrxkRVkHZsyGl4BO6hZnex1hq9aoJASVGHpuY+co6rU4bJQK+Icq6WuQduYQJAaVcM5s3jKNaAMkhOf84ZB6sn7Zz2spggPBBI5beNgiVBveLrVAQPJ/vfGTS+OCDAi/rBWF1yyHHZm8v1oNkkmQJBAPJ5eXbeQngp3s4fi4wc+RuaXVpnwv1HHsUc3JlxfIRcuLthNKZJdLbQO8tjCfnEjztweJP6HjaO6VxZ50o/EDw=
javaPublicKey
:
上面的只是生成公钥和私钥并且是在当前环境测试,也就是iOS测试自己的,Java测试自己的,我上面也已经说了,iOS
端与后台如何进行双向加密的,下面具体测试。
双向加密
iOS
端加密,Java
端解密
iOS
端利用javaPublicKey
加密数据
java
端利用javaPrivate
解密
打印结果:
Java
端加密,iOS
端解密
Java
端利用iOSPublicKey
加密
iOS
端利用iOSPrivateKey
解密
打印结果:
最后
至此,单向加密与双向加密,尤其是与后台之间的加密已经讲完了,因为之前看过一些文章有的很模糊,双向加密的讲解很少,并且一些文章的编辑格式真的是难看,根本就没办法看下去,所以花了一点时间讲讲我对这方面的理解,知识其实很浅,并不高深。
注意点:
1、关于iOS
端保存的私钥和公钥最好是生成文件保存,并且设置密码,这样为了更安全,这个网上都有,可以找找。
2、在RSA
原理上公钥和私钥是可以互相加密互相解密的。公钥加密,私钥解密一般是用于加密数据的,私钥加密公钥解密是用于验证身份的,也就是验证签名。但在iOS端只能用公钥加密私钥解密(不和后台交互,只是在iOS平台),只能用私钥加密公钥验签,请参考文章。如果是和后台进行加密,无论后台是用公钥加密还是私钥加密,iOS端都是可以解的。这个大家可以试试,在RSA文件中,其实他在RSA.h
中已经说明了
// enc with private key NOT working YET!
+ (NSString *)encryptString:(NSString *)str privateKey:(NSString *)privKey;
用私钥加密的方法并未实现,具体iOS
为何不能用私钥加密公钥解密还在搜索资料中,如果有知道的童鞋请告知,不胜感谢。
8月4日解答:关于非对称加密是没有说用私钥加密公钥解密的,私钥只能用来解密和生成签名,公钥只能用来加密和验签,特此声明!
作者:losedMemory链接:https://www.jianshu.com/p/43f7fc8d8e14來源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
iOS开发 RSA加密解密与后台之间的双向加密详解相关推荐
- IOS之RSA加密解密与后台之间的双向加密详解
IOS之RSA加密解密与后台之间的双向加密详解 序言 因为项目中需要用到RSA加密,刚开始也是有点乱,这两天也整理的差不多了,希望能帮到大家. 这次先上代码,我想大部分人肯定是着急解决问题,所以不要废 ...
- 网络通信中的加密解密及openssl和创建私有CA详解
本文大纲: 1.为什么网络通信要进行数据加密? 2.数据加密方式有哪些?它们是如何进行加密的? 3.通信中是如何进行数据加密传输的? 4.https方式进行数据传输的具体流程 5.SSL 的实现工具O ...
- 全网最全之接口测试【加密解密攻防完整版】实战教程详解
看视频讲的更详细:https://www.bilibili.com/video/BV1zr4y1E7V5/? 一.对称加密 对称加密算法是共享密钥加密算法,在加密解密过程中,使用的密钥只有一个.发送和 ...
- 【Android 安全】DEX 加密 ( Java 工具开发 | 加密解密算法 API | 编译代理 Application 依赖库 | 解压依赖库 aar 文件 )
文章目录 一.加密解密算法 API 二.编译代理 Application 依赖库 三.解压代理 Application 依赖库 aar 文件 参考博客 : [Android 安全]DEX 加密 ( 常 ...
- php结合md5的加密解密,php结合md5实现的加密解密方法,php结合md5加密解密_PHP教程...
php结合md5实现的加密解密方法,php结合md5加密解密 本文实例讲述了php结合md5实现的加密解密方法.分享给大家供大家参考,具体如下: 最近在整理代码发现了一个不错的东西,结合md5的加解密 ...
- 【Kotlin】加密解密2:DES、AES加密和解密
文章目录 Api文档 DES加密解密 Base64加密和解密 AES加密解密 DES和AES密钥长度 工作模式和填充模式 对称加密的应用场景 Api文档 https://docs.oracle.com ...
- php 密匙加密解密,带密匙的php加密解密示例分享
这篇文章主要介绍了php加密解密示例,大家参考使用吧 复制代码 代码如下: /************************************************************* ...
- 转:iOS应用程序生命周期(前后台切换,应用的各种状态)详解
iOS应用程序生命周期(前后台切换,应用的各种状态)详解 分类: iOS开发进阶2012-10-08 15:35 42691人阅读 评论(30) 收藏 举报 iosapplication任务anima ...
- java后台验证不能为空_java validation 后台参数验证的使用详解
一.前言 在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节.比如参数不能为null,email那么必须符合email的格式,如果手动进行if判断或者写正则表达式判断无意开发效率太慢,在时间 ...
最新文章
- mysql raw_Oracle中的Raw类型解释
- 宏基因组教程Metagenomics Tutorial (HUMAnN2)
- MSTP和MPLS专线有什么区别?——Vecloud
- Git + Maven + Jenkins 实现自动化部署
- JS实现的一个验证码,可以在前端验证后在提交action
- python2.7个3.7之间传输文件_关于将python2.7转换为python3.7的说明,python27,python37,散记...
- 【黑魔法】Covering Indexes、STRAIGHT_JOIN
- Ajax与Comet
- Java 操作Word书签:用文本、图片、表格替换书签
- matlab 显示图像 去掉边框,Matlab显示图像时去除灰色边框
- 计算机enter代表什么意思,enter是什么意思
- matlab仿真放入直流电源,用Matlab/Simulink软件包建模电容滤波直流电源
- 【汇编作业记录Proteus8+keil5 作业 2】
- html中的字体英文名称
- webpack-图片配置
- Aspen Plus教程-孙兰义-例7.1-质量分数求解摩尔回收率
- 163邮箱 提示xm002 NO SELECT Unsafe Login. Please contact kefu@188.com for help
- 弘辽科技:宝妈开淘宝网店,要不要注册公司才能做电商呢?
- Dictionary(字典)
- C语言——报数问题:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。