美文网首页
iOS RSA加密与解密 签名与验签(附Java端处理)

iOS RSA加密与解密 签名与验签(附Java端处理)

作者: 满庭花醉三千客 | 来源:发表于2019-10-17 14:11 被阅读0次

    本篇文章将涉及以下几个操作:
    1、iOS端使用RSA公钥加密,iOS端使用RSA私钥解密。
    2、iOS端使用RSA私钥加签,iOS端使用RSA公钥验签。
    3、iOS端使用RSA公钥加密,Java端使用RSA私钥解密。
    4、iOS端使用RSA私钥加签,Java端使用RSA公钥验签。

    首先,RSA公钥私钥对,我是由Java端生成的。拿到测试的密钥之后,我在iOS端使用时,添加私钥失败,报错是-50。我后来查了一下资料,得知,Java的文件密钥格式是PKCS8,而iOS需要使用PKCS1格式。这就需要进行一次转换,操作步骤如下:
    1、打开一个文本编辑器(我使用的是Sublime),将Java端给到的私钥拷贝进来,并在首行添加"-----BEGIN PRIVATE KEY-----",在末行添加"-----END PRIVATE KEY-----",完成后的效果是这样的:

    -----BEGIN PRIVATE KEY-----
    MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIYKYkvsosqWTaweZPkY6UjD1wWoSHB+FNoaquoNGfWN8JEOH2ml76ZpuIK+y3qMfkxsJUxUZqpwvKu3MJMBYSyPsYsa9ifROektzGvbDgN//+QYsekafw6v3R+fhIr4+S7k9f3hfZa0DyiylqCZzP/5jRYygdCXm1GzbptZRdrVAgMBAAECgYARlts/S1Yxb3fR1ks5xOMYAVr+Cw82c9UYqdczz3RQnMeswUWt/3BrTgRAY/kfo8APF0HtukWeqByaC/f70nqFxbN4DnLiGsHQRKbFt2dPFV+333M7UIDYgb7Y5fmHmArFZ4ezY+WC24sSsu4+A836d0mfGjSIa03TUH8XI6X5IQJBAMfjcGC2l+TKQLQWODeJEAH2q8SoPsN6BzYUNlPMMJcVoyeqxzy/X/YcLqgdrZD+WrX8g6Y3+RkaRJ/CScDW+RMCQQCrqu0vkEZooNzpbX+o2NJAZL9gzgxXnDe9rH53OjYjbQdD7cacYZ1ZRxehL8/3itPIUy4tZpQbA5e5WL4bBQF3AkAyu914DqA658LIcqNOJTG07eDnBzT29HAEH9kyJ69liY5hsQzktEYs9zY4YV/+XzCy5Cad97L31hz4151UnruVAkBr0zSfh3NyDHg1dj2VBHsrTxyV5VYDQXARhuL4aGvQ3I6PsC3r07RNe0XwTGPIDD7xuK1sft3QCfWmyYK+3eoJAkEAnRxTqRFDbHLejtgLvgjIL52IAURRrliRbN9iyy4t1YqyfOHC7EF/Np11DoVGiBQZrbnPtI7OnNalfIf/l1cTKg==
    -----END PRIVATE KEY-----
    

    2、将这个文本存为pkcs8.pem,放在桌面。
    3、打开终端,执行如下命令:

    openssl rsa -in pkcs8.pem -out pkcs1.pem
    

    完成后效果如下:


    pkcs8转换

    使用cat命令可以看到转换后的内容,我们需要把这个内容拷贝出来,这是我们需要的私钥。

    接下来就是iOS端的加密与解密代码:

    - (void)testEncryptAndDecrypt
    
    {
    
        NSString *string = [NSString stringWithFormat:@"name=wql&age=12&userId=10000&nickname=Kayle"];
    
        //加密时密钥不需要转换
    
        NSString *publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ24IhJQ54nOYQjl49j9lmwUaJJs9RMoyOwfcEmyXrzKE50XyT3IUxYmfB65Zo4PTHb5OndJQnoJfabvHZVeNKj+9Tmi2BXMnQh3BEN2a6HRXBnkySUbLMf9stHrcoOvDsJrZ0PLA1oIZHEoLyKZD/NFqwA0Xng+Rjtf/o14FvIQIDAQAB";
    
        NSString *privateKey = @"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAInbgiElDnic5hCOXj2P2WbBRokmz1EyjI7B9wSbJevMoTnRfJPchTFiZ8Hrlmjg9Mdvk6d0lCegl9pu8dlV40qP71OaLYFcydCHcEQ3ZrodFcGeTJJRssx/2y0etyg68OwmtnQ8sDWghkcSgvIpkP80WrADReeD5GO1/+jXgW8hAgMBAAECgYBCkMCT+o2zRad9ZREyTqxeBoNlpFzEy1C9egEpszSrWEKdZX7u8rNJtkd9hqE5AS6QwlqcqBkFzXClo56aH/PAjIF/2dAhAhrdvNABrxB2h/PdUkTL5XCck1TNy04jzUgxULW/7BScQ0K68A7LNu7282ZzhIG0tYF0aCBObsLE8QJBANuC/iQIoT4aOrhMDwcHeRajgQrB7TekAw1BmOoXOGqzVOHl08b6Gv/NaYXM9QUwK84thpobjApl9+RTZ83jSm0CQQCgxdX9JVibTSRxKjj3XtxiqHnA6n+9zmiZAcgsV2Uo7bMnqsUPJ0CkgAZ4JA5DIDrni1wDM1O9NCRPH7SiKAcFAkBhaVkUbov3fjZOsNn+WY+fv0E1n+eASJVeHZ0ZTOKpXxmtAYuggj7XA7XvPYwCGGVoIoXX/59+wc9nEKhBErtlAkBbJk7gKuBFjELw9eM+PEXumV4OBeVOk0uyE9SNby8nOTytbKA0qyh3Gy6PxsFfRVKgG96a4erEBl/fjDY5CUCRAkEAkZh2Gl1QEnEO2SR/hNnKI60KpGWzt0JNva2EvUZV8eChK8LUqLktggM3M6BOV0jSxpP6YKM+X3eZeFpgvUO4iA==";
    
        NSLog(@"加密前:%@",string);
    
        //加密
    
        NSString *encryptString = [RSAEncryptor encryptString:string publicKey:publicKey];
    
        NSLog(@"加密后:%@",encryptString);
    
        //本地解密
    
        NSString *decryptString = [RSAEncryptor decryptString:encryptString privateKey:privateKey];
    
        NSLog(@"解密后:%@",decryptString);
    
        NSMutableDictionary *param = [NSMutableDictionary dictionary];
    
        [param setObject:encryptString forKey:@"data"];
    
        //后端解密
    
        [self requestWithParam:param withUrlString:@"[http://localhost:8080/api/v1.0/testAPI4](http://localhost:8080/api/v1.0/testAPI4)"];
    
    }
    

    iOS端的签名与验签:

    - (void)testSignAndVerify{
    
        NSString *origin = @"1234567890";
    
        //签名时 私钥需要是pkcs1格式,转换一下才可以使用
    
        NSString *privateKey = @"MIICXAIBAAKBgQCGCmJL7KLKlk2sHmT5GOlIw9cFqEhwfhTaGqrqDRn1jfCRDh9ppe+mabiCvst6jH5MbCVMVGaqcLyrtzCTAWEsj7GLGvYn0TnpLcxr2w4Df//kGLHpGn8Or90fn4SK+Pku5PX94X2WtA8ospagmcz/+Y0WMoHQl5tRs26bWUXa1QIDAQABAoGAEZbbP0tWMW930dZLOcTjGAFa/gsPNnPVGKnXM890UJzHrMFFrf9wa04EQGP5H6PADxdB7bpFnqgcmgv3+9J6hcWzeA5y4hrB0ESmxbdnTxVft99zO1CA2IG+2OX5h5gKxWeHs2PlgtuLErLuPgPN+ndJnxo0iGtN01B/FyOl+SECQQDH43BgtpfkykC0Fjg3iRAB9qvEqD7Degc2FDZTzDCXFaMnqsc8v1/2HC6oHa2Q/lq1/IOmN/kZGkSfwknA1vkTAkEAq6rtL5BGaKDc6W1/qNjSQGS/YM4MV5w3vax+dzo2I20HQ+3GnGGdWUcXoS/P94rTyFMuLWaUGwOXuVi+GwUBdwJAMrvdeA6gOufCyHKjTiUxtO3g5wc09vRwBB/ZMievZYmOYbEM5LRGLPc2OGFf/l8wsuQmnfey99Yc+NedVJ67lQJAa9M0n4dzcgx4NXY9lQR7K08cleVWA0FwEYbi+Ghr0NyOj7At69O0TXtF8ExjyAw+8bitbH7d0An1psmCvt3qCQJBAJ0cU6kRQ2xy3o7YC74IyC+diAFEUa5YkWzfYssuLdWKsnzhwuxBfzaddQ6FRogUGa25z7SOzpzWpXyH/5dXEyo=";
    
        //对数据进行加密
    
        NSString *sign = [RSAEncryptor sign:origin withPriKey:privateKey];
    
        NSLog(@"签名:%@",sign);
    
        //后台验签
    
        [self requestWithParam:@{@"sign":sign==nil?@"":sign} withUrlString:@"[http://localhost:8080/api/v1.0/testAPI3](http://localhost:8080/api/v1.0/testAPI3)"];
    
        //本地验签
    
        NSString *publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGCmJL7KLKlk2sHmT5GOlIw9cFqEhwfhTaGqrqDRn1jfCRDh9ppe+mabiCvst6jH5MbCVMVGaqcLyrtzCTAWEsj7GLGvYn0TnpLcxr2w4Df//kGLHpGn8Or90fn4SK+Pku5PX94X2WtA8ospagmcz/+Y0WMoHQl5tRs26bWUXa1QIDAQAB";
    
        BOOL success = [RSAEncryptor verify:origin signature:sign withPublivKey:publicKey];
    
        NSLog(@"是否验证成功:%@",success?@"YES":@"NO");
    
    }
    

    核心代码在RSAEncryptor文件中。

    然后是Java端验签:

    @RequestMapping(value = "api/v1.0/testAPI3", method = RequestMethod.GET)
    public Object queryThree(@RequestParam(value = "sign",required = true)String signStr){
        String string = "1234567890";
        boolean success = RSAUtil.verifyIdentify(string,signStr);
        System.out.println("验证成功?======="+(success?"YES":"NO"));
        return success;
    }
    

    Java端解密:

    @RequestMapping(value = "api/v1.0/testAPI4", method = RequestMethod.GET)
    public Object queryFour(@RequestParam(value = "data",required = true)String dataString){
        String decryptData = RSAUtil.decrypt(dataString);
        System.out.println("解密结果:"+decryptData);
        return decryptData;
    }
    

    核心代码在RSAUtil中。

    接下来是iOS端本地效果:


    iOS本地效果

    Java端的验签与解密效果:


    Java端效果

    可以看到我们的签名与验签是通过了,解密的数据Java端也是成功拿到了。
    代码在这里(含Java的核心代码)
    加油~

    相关文章

      网友评论

          本文标题:iOS RSA加密与解密 签名与验签(附Java端处理)

          本文链接:https://www.haomeiwen.com/subject/xbemmctx.html