Android通过RSA加密解密实现License

Android通过RSA加密解密实现License

1. linux下用openssl生成RSA私钥和公钥(我是在windows 7下用cygwin生成的)

(参考博客: http://blog.csdn.net/chaijunkun/article/details/7275632/)

 1)首先确认系统安装了openssl。如果没安装可以使用命令:sudo apt-get install openssl

 2)输入openssl命令,进入openssl的交互界面

 $ openssl
OpenSSL>

3)生成RSA私钥

genrsa -out rsa_private_key.pem 1024

该命令会生成1024位的私钥,生成成功的界面如下:

 OpenSSL> genrsa -out rsa_private_key.pem 1024
Generating RSA private key, 1024 bit long modulus
....++++++
.....++++++
e is 65537 (0x10001)
OpenSSL>

此时我们就可以在当前路径下看到rsa_private_key.pem文件了。

 

4)生成RSA公钥

输入命令rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem,并回车,

得到生成成功的结果,如下:

 OpenSSL> genrsa -out rsa_private_key.pem 1024
Generating RSA private key, 1024 bit long modulus
....++++++
.....++++++
e is 65537 (0x10001)
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
writing RSA key

此时,我们可以看到一个文件名为rsa_public_key.pem的文件,如图:


打开它,可以看到-----BEGIN PUBLIC KEY-----开头,
-----END PUBLIC KEY-----结尾的没有换行的字符串,这个就是公钥

5)RSA私钥转换成PKCS8格式

输入命令pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM –nocrypt,并回车得到生成功的结果,这个结果就是PKCS8格式的私钥,如下:

 OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM –nocrypt
Enter Encryption Password:
Verifying - Enter Encryption Password:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIICoTAbBgkqhkiG9w0BBQMwDgQI8iRfyoDFI3kCAggABIICgFRPGuWBmhljGSQ6
tT0qRR8RnCpyBcp5JvzVPoqOL6qRqjQlKlqjBoEtYdUU9+daAs1yNW6pCOyQQyKV
eWurd6ls0GRikspaCfRhxMgIny5LKdMwhhJfCByjnrnKqnK+3hUeBCwu57pXRtOK
nch0IexK4OV1AfaroAwZ/w5oYalTBMePJunuzatS566q+IKLMsBtVc9NMTC2f5e2
4Wg04jkmmFPDYv9LzJCRgSMuL8Gf056ls/dpQdUwfN6ni2EoLaqEXTJo/A0K0pFb
2fhvzxOOLGn2sGtZ+SDuB65xjwNKnr2dkmm2G1A2mBR8accIo04pzOcAw3lYc9q3
NyWWw55jqCnJoZVQWz892uXEykMFXcnwW4o45Hk88Xddo3EKafME3D7Vs/3OLzPF
D978BpGsLw3Ja/jzbkQ3/r9ZkJ0wN3X0z9acnthmWpHmqQHIa4obGSlT5O62y8Vz
ZloqgWv/IfRZRT3H7+pmid8MGnMYpibiHhUFxGsoKgn1u2P1lYi8CzAlA6cTbpNp
MBqduCAumSi5JzwRG1dtYpYJ/TsYQR07AYiFfWIzW1fZtrwK/VWnSZ4+2TVkAji/
JN0VwwfETXVeuHsFIQ9AJ2wCcViCACKG7C87kCBLC4edC1R9u3te9CqNZ+kppYjY
MSTMzoTWB2d6lXI+arNvSmXvlGd7nIypjrD1r3TCNZDac3UhODUZRFxZzGAuffit
KCQiLML9ePkQzPGBSpjMW2RD1Q1sbybLh0ZwwXS86lqGpD6WfUP7ssreySchNvRX
jlm0IrUAiE80NWkCOZKbBu/r/yDSIC1gz3t9WXiKcMc5RXbqdBDJZOLb9K54duoB
1nwBAkw=
-----END ENCRYPTED PRIVATE KEY-----

输入该命令如果提示输入密码直接回车即可。

在实际开发过程中,公钥的生成是私钥没有经过PKCS8转换生成的。所以在私钥加密过程中,必须用未转换格式私钥,对应的公钥才能解密.

2. RSA加密解密(android)

  1)首先要导入两个BASE64操作相关的类:

import Decoder.BASE64Decoder;
import Decoder.BASE64Encoder;

这两个包从sun.misc.BASE64Decoder.jar中导入,网上可下载。

用到这个包是因为RSA加密后的密文自动进行了BASE64加密。

  2)具体实现代码如下(为了方便测试,代码中的公钥私钥跟上面的不同):

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import android.widget.EditText;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.StreamCorruptedException;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.List;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import Decoder.BASE64Decoder;
import Decoder.BASE64Encoder;

public final class Utils {
    public static final StringSOURCE="1234abcd"; // 要加密的原文

    /* openssl生成的私钥 */
    public static finalStringPRIVATE_KEY="MIICWwIBAAKBgQC0GU7gWV1iRj1WIxV4GwxRVobmNtiKke6ku21Jm99Mds2ZgpBO"+"\r"
    +"ksrprPkgdrxnJSKUlgnkYC7rImLbfpYqXzlwscV6BCR8srAl0odk93qffLb4Q0kN"+"\r"
    +"pNtpjUyoJuppWd7oiOHAe+w2Tjl95PIW4Dq5tBBCD3Su/YQy2wScMvLpqwIDAQAB"+"\r"
    +"AoGAJFkzRS5kHZCFkpv0GlCDNOtcwJvzKkx3uMGnNgMCl2Em78OdMm6IC4+AnF+6"+"\r"
    +"eKrTBuAdUP1kmspO33P2BMlBQzl0zqpSrhR/tZ3l4mKB0/3Qqn6wycQawgc4CcYI"+"\r"
    +"qbQFPqSESPinRArqR581H941i4EbHgg/6CODb2hvbxxaLEkCQQDpUknAmLtFVnyZ"+"\r"
    +"bZjUh122F4Jdo2yBQ+ADEQm8z5ivBA/gs8I7V0rx4uMYOd2v3VuEWz9i8Ue2JKN7"+"\r"
    +"xKut5KMVAkEAxZqwO3ftzZ9zWR9dsWnZyraaMuxmQ+Jbzlvh9bMA4p2ikO+9eXWm"+"\r"
    +"DJyKeXtBd1RB744CPbEDnXg9BZWIg3uJvwJAdHhiXqUfXsaEnmZqUzVbn0lvB2VM"+"\r"
    +"Bd8nFQDNVpZexocFkgrJ26uAuuyipnZEZsTeKV0PcEm3nYH+pgsQFFc83QJAXRV5"+"\r"
    +"Xwono20xURJNeH18ctmB2esyYVgIFzWBQ9SG3jmTkuLcRpL9HYPAV2mQdT3jsY0b"+"\r"
    +"0SPJqCwz0qWWIRnY0QJATA7t4lUgc+0Wp9rPbcfB1qCr9mHVpvPcv59DX5nukk75"+"\r"
    +"5DzQmErPJzsF6Kl7qITXJmDDFawE91nowIA0dCka2Q=="+"\r";

    /* openssl生成的公钥 */
    public static finalStringPUCLIC_KEY="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0GU7gWV1iRj1WIxV4GwxRVobm"+"\r"
            +"NtiKke6ku21Jm99Mds2ZgpBOksrprPkgdrxnJSKUlgnkYC7rImLbfpYqXzlwscV6"+"\r"
            +"BCR8srAl0odk93qffLb4Q0kNpNtpjUyoJuppWd7oiOHAe+w2Tjl95PIW4Dq5tBBC"+"\r"
            +"D3Su/YQy2wScMvLpqwIDAQAB"+"\r";

    private static BASE64Encoderencoder;
    private static BASE64Decoderdecoder;

    public static  BASE64EncodergetEncoder() {
        if(encoder==null) {
            return newBASE64Encoder();
        }
        returnencoder;
    }

    public staticBASE64DecodergetDecoder() {
        if(decoder==null) {
            return newBASE64Decoder();
        }
        returndecoder;
    }

        /**
     * 从字符串中加载私钥
     * 加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。
     *
@paramprivateKeyStr
     *
@return
     
*@throwsException
     */
    
public staticPrivateKeyloadPrivateKeyFromString(String privateKeyStr)throwsException {
        try{
            byte[] buffer =getDecoder().decodeBuffer(privateKeyStr); // 解开私钥的base64
            PKCS8EncodedKeySpec keySpec =newPKCS8EncodedKeySpec(buffer);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA","BC");
            RSAPrivateKey priKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
            Log.e("hubin","loadPrivateKeyFromString-->priKey="+ priKey);
            return priKey;
        }catch(NoSuchAlgorithmException e) {
            throw newException("无此算法");
        }catch(InvalidKeySpecException e) {
            Log.e("hubin","私钥非法 :" + e);
            e.printStackTrace();
        }catch(NullPointerException e) {
            throw newException("私钥数据为空");
        }
        return null;
    }

    /**
     * RSA私钥加密
     *
@paramdata明文字节数组
     *
@param  privateKey私钥
     * */
    
public static byte[]encryptDataByPrivateKey(byte[] data,PrivateKey privateKey) {
        try{
            Cipher cipher = Cipher.getInstance("RSA");
            // 编码前设定编码方式及密钥
            cipher.init(Cipher.ENCRYPT_MODE,privateKey);
            // 传入编码数据并返回编码结果
            returncipher.doFinal(data);
        }catch(Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /*从字符串中加载公钥 */
    public staticPublicKeyloadPublicKeyFromString(String publicKeyStr)throwsException {
        try{
            byte[] buffer =getDecoder().decodeBuffer(publicKeyStr); // 解开公钥的base4
            KeyFactory keyFactory = KeyFactory.getInstance("RSA","BC");
            X509EncodedKeySpec keySpec =newX509EncodedKeySpec(buffer);
            RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
            Log.e("hubin","loadPublicKeyFromString-->pubKey="+ pubKey);
            return pubKey;
        }catch(NoSuchAlgorithmException e) {
            Log.e("hubin","NoSuchAlgorithmException="+ e);
        }catch(InvalidKeySpecException e) {
            Log.e("hubin","InvalidKeySpecException=="+ e);
        }catch(NullPointerException e) {
            Log.e("hubin","NullPointerException==="+ e);
        }
        return null;
    }

    /**
     * 用公钥解密
     *
     *
@paramencryptedData
     *            经过encryptDataByPrivateKey()加密返回的byte数据
     *
@parampublicKey
     *            公钥
     *
@return
     
*/
    
public static byte[]decryptDataByPublicKey(byte[] encryptedData,PublicKey publicKey) {
        try{
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE,publicKey);
            return cipher.doFinal(encryptedData);
        }catch(Exception e) {
            return null;
        }
    }

 }

3)调用加密解密方法

try {
    //私钥加密
    byte[] rsaByte = LicenseUtil.encryptDataByPrivateKey(LicenseUtil.SOURCE.getBytes(),

            LicenseUtil.loadPrivateKeyFromString(LicenseUtil.PRIVATE_KEY));
    //公钥解密
    byte[] rsaDByte = LicenseUtil.decryptDataByPublicKey(rsaByte,LicenseUtil.loadPublicKeyFromString(LicenseUtil.PUCLIC_KEY));
    String str =newString(rsaDByte); // 生成解密后的明文字符串
    Log.e("hubin","rsa decode str=" + str); //打印解密结果,1234abcd
} catch(Exception e) {
    e.printStackTrace();
}

猜你喜欢

转载自blog.csdn.net/LikeSidehu/article/details/78957212