转载自: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这是一个封装的第三方框架,只需要将下面这两个文件导入到项目中,便可以使用(不用再导入其他的一些框架),别的框架不敢保证能使用,但这个是肯定可以使用的。

1.png

代码:

 //公钥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);

打印结果:

2

这只是先进行测试的数据,如果给你私钥解密,就用别的方法,在RSA.h中可以很容易找到。
上面讲述的是单向加密,那么如何进行双向加密呢?

  • 1、 iOS端和后台(这里后台使用的是java,因为我后台语言只会java,效果都是一样的)各生成自己的公钥和私钥。
  • 2、 iOS端生成的公钥和私钥定义为iOSPublicKeyiOSPrivateKeyjava端生成的公钥私钥定义为javaPublicKeyjavaPrivateKey。将iOSPublicKeyjava,让它用iOSPublicKey加密数据传给iOS端,iOS端用iOSPrivateKey解密;java端将javaPublicKeyiOS端,iOS端用javaPublicKey加密数据后上传给javajava端利用javaPrivateKey去解密,这样就实现了数据传输过程中的加密与解密,当然,也不一定非要按照我上面的步骤来,具体情况要和后台商量如何加密。

具体实现:

iOS端
  • 生成公钥和私钥

1)新建文件夹,用来保存生成的私钥和公钥,打开终端 cd 新建,进入到新建文件夹中,openssl,打开openssl

3

  1. genrsa -out rsa_private_key.pem 1024生成私钥
4

  1. pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt这步一定要有,需要将私钥转成PKCS8的格式才能使用,此时复制私钥(先复制私钥,然后在4步取出公钥)
5

4)rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 生成公钥

6

此时在新建文件夹中会出现两个文件

7

我们用文本编辑器打开便可获取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);

打印结果:

8

经过测试,私钥和公钥是可以使用的。

Java端

我是用的是Eclipse,具体实现方法也是从网上找的,因为打开的东西太多,忘了是哪篇博客了,知道的请联系我,会注明作者的。

  • 前期准备
9

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);  }
}

打印结果:

10

在此,我们可以获取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加密数据
11

java端利用javaPrivate解密

12

打印结果:

13

  • Java端加密,iOS端解密
    Java端利用 iOSPublicKey加密
14

15

iOS端利用iOSPrivateKey解密

16

打印结果:

17

最后

至此,单向加密与双向加密,尤其是与后台之间的加密已经讲完了,因为之前看过一些文章有的很模糊,双向加密的讲解很少,并且一些文章的编辑格式真的是难看,根本就没办法看下去,所以花了一点时间讲讲我对这方面的理解,知识其实很浅,并不高深。
注意点:
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加密解密与后台之间的双向加密详解相关推荐

  1. IOS之RSA加密解密与后台之间的双向加密详解

    IOS之RSA加密解密与后台之间的双向加密详解 序言 因为项目中需要用到RSA加密,刚开始也是有点乱,这两天也整理的差不多了,希望能帮到大家. 这次先上代码,我想大部分人肯定是着急解决问题,所以不要废 ...

  2. 网络通信中的加密解密及openssl和创建私有CA详解

    本文大纲: 1.为什么网络通信要进行数据加密? 2.数据加密方式有哪些?它们是如何进行加密的? 3.通信中是如何进行数据加密传输的? 4.https方式进行数据传输的具体流程 5.SSL 的实现工具O ...

  3. 全网最全之接口测试【加密解密攻防完整版】实战教程详解

    看视频讲的更详细:https://www.bilibili.com/video/BV1zr4y1E7V5/? 一.对称加密 对称加密算法是共享密钥加密算法,在加密解密过程中,使用的密钥只有一个.发送和 ...

  4. 【Android 安全】DEX 加密 ( Java 工具开发 | 加密解密算法 API | 编译代理 Application 依赖库 | 解压依赖库 aar 文件 )

    文章目录 一.加密解密算法 API 二.编译代理 Application 依赖库 三.解压代理 Application 依赖库 aar 文件 参考博客 : [Android 安全]DEX 加密 ( 常 ...

  5. php结合md5的加密解密,php结合md5实现的加密解密方法,php结合md5加密解密_PHP教程...

    php结合md5实现的加密解密方法,php结合md5加密解密 本文实例讲述了php结合md5实现的加密解密方法.分享给大家供大家参考,具体如下: 最近在整理代码发现了一个不错的东西,结合md5的加解密 ...

  6. 【Kotlin】加密解密2:DES、AES加密和解密

    文章目录 Api文档 DES加密解密 Base64加密和解密 AES加密解密 DES和AES密钥长度 工作模式和填充模式 对称加密的应用场景 Api文档 https://docs.oracle.com ...

  7. php 密匙加密解密,带密匙的php加密解密示例分享

    这篇文章主要介绍了php加密解密示例,大家参考使用吧 复制代码 代码如下: /************************************************************* ...

  8. 转:iOS应用程序生命周期(前后台切换,应用的各种状态)详解

    iOS应用程序生命周期(前后台切换,应用的各种状态)详解 分类: iOS开发进阶2012-10-08 15:35 42691人阅读 评论(30) 收藏 举报 iosapplication任务anima ...

  9. java后台验证不能为空_java validation 后台参数验证的使用详解

    一.前言 在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节.比如参数不能为null,email那么必须符合email的格式,如果手动进行if判断或者写正则表达式判断无意开发效率太慢,在时间 ...

最新文章

  1. mysql raw_Oracle中的Raw类型解释
  2. 宏基因组教程Metagenomics Tutorial (HUMAnN2)
  3. MSTP和MPLS专线有什么区别?——Vecloud
  4. Git + Maven + Jenkins 实现自动化部署
  5. JS实现的一个验证码,可以在前端验证后在提交action
  6. python2.7个3.7之间传输文件_关于将python2.7转换为python3.7的说明,python27,python37,散记...
  7. 【黑魔法】Covering Indexes、STRAIGHT_JOIN
  8. Ajax与Comet
  9. Java 操作Word书签:用文本、图片、表格替换书签
  10. matlab 显示图像 去掉边框,Matlab显示图像时去除灰色边框
  11. 计算机enter代表什么意思,enter是什么意思
  12. matlab仿真放入直流电源,用Matlab/Simulink软件包建模电容滤波直流电源
  13. 【汇编作业记录Proteus8+keil5 作业 2】
  14. html中的字体英文名称
  15. webpack-图片配置
  16. Aspen Plus教程-孙兰义-例7.1-质量分数求解摩尔回收率
  17. 163邮箱 提示xm002 NO SELECT Unsafe Login. Please contact kefu@188.com for help
  18. 弘辽科技:宝妈开淘宝网店,要不要注册公司才能做电商呢?
  19. Dictionary(字典)
  20. C语言——报数问题:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

热门文章

  1. Joost 不能启动: tvprunner.exe 应用程序错误
  2. w ndows10主题,从《Microsoft Store微软商店》获取精美免费Win10主题
  3. 金蝶EAS本地WebService发布
  4. Nacos 启动报错
  5. 从逻辑分区中划出主分区
  6. 第一次亲密接触(3)
  7. arthas启动-attach流程
  8. 基于图论的色谱指纹图谱谱峰的全局匹配
  9. java 字符串截取的几种方式
  10. Internet协议---UDP(一)