android、ios与服务器端php使用rsa加密解密通讯

发布时间:2016-12-7 16:42:48 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"android、ios与服务器端php使用rsa加密解密通讯",主要涉及到android、ios与服务器端php使用rsa加密解密通讯方面的内容,对于android、ios与服务器端php使用rsa加密解密通讯感兴趣的同学可以参考一下。

转自:http://blog.csdn.net/lx923988898/article/details/10374145 下载RSA密钥生成工具openssl,点击下载,解压缩至独立的文件夹,进入其中的bin目录,执行以下命令: 1 2 3 4 5 openssl genrsa -out rsa_private_key.pem 1024   openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem   openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 第一条命令生成原始 RSA私钥文件 rsa_private_key.pem,第二条命令将原始 RSA私钥转换为 pkcs8格式,第三条生成RSA公钥 rsa_public_key.pem 从上面看出通过私钥能生成对应的公钥,因此我们将私钥private_key.pem用在服务器端,公钥发放给android跟ios等前端 第二步,php服务器端,使用openssl方法来进行加密解密类,代码如下: <?php /**  * @author alun (http://alunblog.duapp.com)  * @version 1.0  * @created 2013-5-17  */   class Rsa { private static $PRIVATE_KEY = '-----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAM9nUm7rPNhSgvsd jMuCd5E7IMJB/80A1YY7jYV9fBCKdhVKmqea26QYuw6FW7B00fppEUTSazduSmn9 Yvhx9UOCcI75b0nq9FWm5O4P+Kp8l31M1pwsJ3cm+DceGOrFsl47vh9idiqj+abI lJ4sTmJmDghmbks9YFlZSndQsIBlAgMBAAECgYAasa6vbgF3yi7niScc7l7bR2Pw /LOivA+/ZhzR6JO2QUvvc5myJsFMPo6c0Nc7P93iv/EkDX0VNlHHkIBTf79URHXM gXwMad4pHAeOiqxk5A9w/szDCBoETngtoqQGJq+QINxwPVvDEO4i224Uj3MKg2fo 4SDy3P1GCAAj1ahNoQJBAP4FV9vLWdLOOwOLnBpXt6vru4HT5VIf9fCeBIemuQ4C /yRtgU38zXWgZ8AAmS6EjBEUDnN/tWid6UBKfgPDwAkCQQDRBP+Y9wIYIaSxeL7B nHhPT25yAJCGK+l6r2qeaHVQr81O9YjusEi8E2M5OxCRolKxC3L7hrLJX8z1oyOV dNx9AkBqYGhzpgv+qNiz2mJL8dH8ECMc8lTFeJbw5eu1tw8mHAEnCyisNSMBkGQC Vv3PKjjR6hlHKwMYRZDpmIh/IRmpAkEAr1soLGaeZSxkhVetgbUJ4k/bct0yYr4Y ZQshwcAVHBpBforT1JwkiVUim3MIFYY/JbVbQ9XfzL4Ir9OsGMkv6QJAPaQnyNY5 /D0PhXqODOM6jtAHHRfaSi4gve6AZ0iRz6YlB8beJ1ywZaJZWD9Cuw3zy4dDpCOn A4tBsIdpMMoT+w== -----END PRIVATE KEY-----';     /**     *返回对应的私钥     */     private static function getPrivateKey(){              $privKey = self::$PRIVATE_KEY;                   return openssl_pkey_get_private($privKey);          }       /**      * 私钥加密      */     public static function privEncrypt($data)     {         if(!is_string($data)){                 return null;         }                   return openssl_private_encrypt($data,$encrypted,self::getPrivateKey())? base64_encode($encrypted) : null;     }               /**      * 私钥解密      */     public static function privDecrypt($encrypted)     {         if(!is_string($encrypted)){                 return null;         }         return (openssl_private_decrypt(base64_decode($encrypted), $decrypted, self::getPrivateKey()))? $decrypted : null;     } } ?> 打开private_key.pem,将上面的$PRIVATE_KEY,替换成private_key.pem的内容即可,服务器端我们只需要使用私钥来加密解密。 第三步,android前端,使用java的Cipher类来实现加密解密类,代码如下: import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher;   import android.util.Base64;   /**  * @author alun (http://alunblog.duapp.com)  * @version 1.0  * @created 2013-5-17  */ public class Rsa {     private static final String RSA_PUBLICE =             "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPZ1Ju6zzYUoL7HYzLgneROyDC" + "\r" +             "Qf/NANWGO42FfXwQinYVSpqnmtukGLsOhVuwdNH6aRFE0ms3bkpp/WL4cfVDgnCO" + "\r" +             "+W9J6vRVpuTuD/iqfJd9TNacLCd3Jvg3HhjqxbJeO74fYnYqo/mmyJSeLE5iZg4I" + "\r" +             "Zm5LPWBZWUp3ULCAZQIDAQAB";     private static final String ALGORITHM = "RSA";       /**      * 得到公钥      * @param algorithm      * @param bysKey      * @return      */     private static PublicKey getPublicKeyFromX509(String algorithm,             String bysKey) throws NoSuchAlgorithmException, Exception {         byte[] decodedKey = Base64.decode(bysKey,Base64.DEFAULT);         X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodedKey);           KeyFactory keyFactory = KeyFactory.getInstance(algorithm);         return keyFactory.generatePublic(x509);     }       /**      * 使用公钥加密      * @param content      * @param key      * @return      */     public static String encryptByPublic(String content) {         try {             PublicKey pubkey = getPublicKeyFromX509(ALGORITHM, RSA_PUBLICE);               Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");             cipher.init(Cipher.ENCRYPT_MODE, pubkey);               byte plaintext[] = content.getBytes("UTF-8");             byte[] output = cipher.doFinal(plaintext);               String s = new String(Base64.encode(output,Base64.DEFAULT));               return s;           } catch (Exception e) {             return null;         }     }       /**     * 使用公钥解密     * @param content 密文     * @param key 商户私钥     * @return 解密后的字符串     */     public static String decryptByPublic(String content) {         try {             PublicKey pubkey = getPublicKeyFromX509(ALGORITHM, RSA_PUBLICE);             Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");             cipher.init(Cipher.DECRYPT_MODE, pubkey);             InputStream ins = new ByteArrayInputStream(Base64.decode(content,Base64.DEFAULT));             ByteArrayOutputStream writer = new ByteArrayOutputStream();             byte[] buf = new byte[128];             int bufl;             while ((bufl = ins.read(buf)) != -1) {                 byte[] block = null;                 if (buf.length == bufl) {                 block = buf;                 } else {                 block = new byte[bufl];                 for (int i = 0; i < bufl; i++) {                     block[i] = buf[i];                 }                 }                 writer.write(cipher.doFinal(block));             }             return new String(writer.toByteArray(), "utf-8");         } catch (Exception e) {             return null;         }     }   } 需要注意的是,在初始化Cipher对象时,一定要指明使用"RSA/ECB/PKCS1Padding"格式如Cipher.getInstance("RSA/ECB/PKCS1Padding"); 打开rsa_public_key.pem文件,将上面代码的RSA_PUBLICE替换成其中内容即可。 第四步,ios前端,iOS上没有直接处理RSA加密的API,网上说的大多数也是处理X.509的证书的方法来实现,不过X.509证书是带签名的,在php端openssl_pkey_get_private方法获取密钥时,第二个参数需要传签名,而android端实现X.509证书加密解密较为不易,在这里我们利用ios兼容c程序的特点,利用openssl的api实现rsa的加密解密,代码如下: CRSA.h代码: #import <Foundation/Foundation.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/err.h>   typedef enum {     KeyTypePublic,     KeyTypePrivate }KeyType;   typedef enum {     RSA_PADDING_TYPE_NONE       = RSA_NO_PADDING,     RSA_PADDING_TYPE_PKCS1      = RSA_PKCS1_PADDING,     RSA_PADDING_TYPE_SSLV23     = RSA_SSLV23_PADDING }RSA_PADDING_TYPE;   @interface CRSA : NSObject{     RSA *_rsa; } + (id)shareInstance; - (BOOL)importRSAKeyWithType:(KeyType)type; - (int)getBlockSizeWithRSA_PADDING_TYPE:(RSA_PADDING_TYPE)padding_type; - (NSString *) encryptByRsa:(NSString*)content withKeyType:(KeyType)keyType; - (NSString *) decryptByRsa:(NSString*)content withKeyType:(KeyType)keyType; @end CRSA.m代码 #import "CRSA.h"   #define BUFFSIZE  1024 #import "Base64.h"   #define PADDING RSA_PADDING_TYPE_PKCS1 @implementation CRSA   + (id)shareInstance {     static CRSA *_crsa = nil;     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{         _crsa = [[self alloc] init];     });     return _crsa; } - (BOOL)importRSAKeyWithType:(KeyType)type {     FILE *file;     NSString *keyName = type == KeyTypePublic ? @"public_key" : @"private_key";     NSString *keyPath = [[NSBundle mainBundle] pathForResource:keyName ofType:@"pem"];           file = fopen([keyPath UTF8String], "rb");           if (NULL != file)     {         if (type == KeyTypePublic)         {             _rsa = PEM_read_RSA_PUBKEY(file, NULL, NULL, NULL);             assert(_rsa != NULL);         }         else         {             _rsa = PEM_read_RSAPrivateKey(file, NULL, NULL, NULL);             assert(_rsa != NULL);         }                   fclose(file);                   return (_rsa != NULL) ? YES : NO;     }           return NO; }   - (NSString *) encryptByRsa:(NSString*)content withKeyType:(KeyType)keyType {     if (![self importRSAKeyWithType:keyType])          return nil;           int status;     int length  = [content length];     unsigned char input[length + 1];     bzero(input, length + 1);     int i = 0;     for (; i < length; i++)     {         input[i] = [content characterAtIndex:i];     }           NSInteger  flen = [self getBlockSizeWithRSA_PADDING_TYPE:PADDING];           char *encData = (char*)malloc(flen);     bzero(encData, flen);           switch (keyType) {         case KeyTypePublic:             status = RSA_public_encrypt(length, (unsigned char*)input, (unsigned char*)encData, _rsa, PADDING);             break;                       default:             status = RSA_private_encrypt(length, (unsigned char*)input, (unsigned char*)encData, _rsa, PADDING);             break;     }           if (status)     {         NSData *returnData = [NSData dataWithBytes:encData length:status];         free(encData);         encData = NULL;                   NSString *ret = [returnData base64EncodedString];         return ret;     }           free(encData);     encData = NULL;           return nil; }   - (NSString *) decryptByRsa:(NSString*)content withKeyType:(KeyType)keyType {     if (![self importRSAKeyWithType:keyType])         return nil;           int status;       NSData *data = [content base64DecodedData];     int length = [data length];           NSInteger flen = [self getBlockSizeWithRSA_PADDING_TYPE:PADDING];     char *decData = (char*)malloc(flen);     bzero(decData, flen);           switch (keyType) {         case KeyTypePublic:             status = RSA_public_decrypt(length, (unsigned char*)[data bytes], (unsigned char*)decData, _rsa, PADDING);             break;                       default:             status = RSA_private_decrypt(length, (unsigned char*)[data bytes], (unsigned char*)decData, _rsa, PADDING);             break;     }           if (status)     {         NSMutableString *decryptString = [[NSMutableString alloc] initWithBytes:decData length:strlen(decData) encoding:NSASCIIStringEncoding];         free(decData);         decData = NULL;                   return decryptString;     }           free(decData);     decData = NULL;           return nil; }   - (int)getBlockSizeWithRSA_PADDING_TYPE:(RSA_PADDING_TYPE)padding_type {     int len = RSA_size(_rsa);           if (padding_type == RSA_PADDING_TYPE_PKCS1 || padding_type == RSA_PADDING_TYPE_SSLV23) {         len -= 11;     }           return len; } @end 其中openssl api包,我们可以在第一步RSA密钥生成工具openssl的include文件夹中得到,完整代码包请点击这里下载

上一篇:自己收藏:java 词汇表
下一篇:日语特殊字符打法

相关文章

相关评论