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

?p=50

点击打开链接

最近做手机项目,服务器端使用的是php,客户端分别有android版及ios版,在部分通讯环节需要对内容进行加密,RSA加密演算法是一种非对称加密演算法,能够较好达到要求,不过如果服务器架设https服务,较为麻烦,系统效率也不高,我们只需要在部分重要接口上使用RSA加密解密就行。

首先,准备工作下载RSA密钥生成工具openssl,点击下载,解压缩至独立的文件夹,进入其中的bin目录,执行以下命令: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 () * @version 1.0 * @created 2013-5-17 */ class Rsa{private static $PRIVATE_KEY = ‘—–BEGIN PRIVATE KEY—–MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAM9nUm7rPNhSgvsdjMuCd5E7IMJB/80A1YY7jYV9fBCKdhVKmqea26QYuw6FW7B00fppEUTSazduSmn9Yvhx9UOCcI75b0nq9FWm5O4P+Kp8l31M1pwsJ3cm+DceGOrFsl47vh9idiqj+abIlJ4sTmJmDghmbks9YFlZSndQsIBlAgMBAAECgYAasa6vbgF3yi7niScc7l7bR2Pw/LOivA+/ZhzR6JO2QUvvc5myJsFMPo6c0Nc7P93iv/EkDX0VNlHHkIBTf79URHXMgXwMad4pHAeOiqxk5A9w/szDCBoETngtoqQGJq+QINxwPVvDEO4i224Uj3MKg2fo4SDy3P1GCAAj1ahNoQJBAP4FV9vLWdLOOwOLnBpXt6vru4HT5VIf9fCeBIemuQ4C/yRtgU38zXWgZ8AAmS6EjBEUDnN/tWid6UBKfgPDwAkCQQDRBP+Y9wIYIaSxeL7BnHhPT25yAJCGK+l6r2qeaHVQr81O9YjusEi8E2M5OxCRolKxC3L7hrLJX8z1oyOVdNx9AkBqYGhzpgv+qNiz2mJL8dH8ECMc8lTFeJbw5eu1tw8mHAEnCyisNSMBkGQCVv3PKjjR6hlHKwMYRZDpmIh/IRmpAkEAr1soLGaeZSxkhVetgbUJ4k/bct0yYr4YZQshwcAVHBpBforT1JwkiVUim3MIFYY/JbVbQ9XfzL4Ir9OsGMkv6QJAPaQnyNY5/D0PhXqODOM6jtAHHRfaSi4gve6AZ0iRz6YlB8beJ1ywZaJZWD9Cuw3zy4dDpCOnA4tBsIdpMMoT+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 () * @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的加密解密,代码如下:今天不想走,明天就要跑了。

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

相关文章:

你感兴趣的文章:

标签云: