Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android應用開發中如何使用RSA加密算法對數據進行校驗

Android應用開發中如何使用RSA加密算法對數據進行校驗

編輯:關於Android編程

這個世界很精彩,這個世界很無奈。是的,在互聯網時代,如何保護自己的數據,如何對數據進行加密和效驗就變得非常的重要。這裡總結一下Android平台使用Java語言,利用RSA算法對數據進行校驗的經驗。

先來看下如何RSA加密算法對數據進行校驗的流程:

1、首先要用openssh之類的程序生成一個私鑰

2、再根據私鑰生成一個公鑰

3、使用私鑰和公鑰,對數據進行簽名,得到簽名文件。

4、使用公鑰和簽名文件就可以對數據進行校驗了。

 

再來看下如何實現:

1、生成2048位的私鑰:

 

openssl genrsa -out private.pem 2048

 

 

2、生成公鑰

使用openssh也可以生成公鑰,但是在使用的過程中,發現由於格式的問題,使用openssh生成的公鑰在Java中使用時總是提示異常,所以最後還是根據網上的相關資料,使用Java語言來寫了程序,使用的公鑰可以在Java中使用,代碼如下:

GenPublic.java

 

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.RSAPublicKeySpec;

import javax.xml.bind.DatatypeConverter;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.util.encoders.Base64;


public class GenPublic {

    public static PrintStream out = System.out;
    public static PrintStream err = System.err;

    private static void genPublicKey(String privateFile,String pubFile) {
        try {
    	    PEMReader pemReader = new PEMReader(new FileReader(privateFile));
    	    KeyPair pair = (KeyPair)pemReader.readObject();
    	    PublicKey pubKey = pair.getPublic();
    	    FileOutputStream outPub = new FileOutputStream(pubFile);
    		byte[] bytes = pair.getPublic().getEncoded();
    		outPub.write(bytes);
    		outPub.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
	}

    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            err.println(Usage: java GenPublic   );
            System.exit(1);
        }
        File pemFile = new File(args[0]);
        if(!pemFile.exists()) {
            err.println(PEM File Does Not Exist);
            System.exit(1);
        }
        Security.addProvider(new BouncyCastleProvider());
        genPublicKey(args[0],args[1]);
    }
}

 

使用方法:

 

先編譯:

 

export CLASSPATH=.:bcprov-jdk15-140.jar
javac GenPublic.java 

 

再使用編譯的程序生成公鑰:

 

java GenPublic private.pem public.bin

 

用到的庫可以在本文最後的鏈接中下載。

 

 

再來看看生成簽名文件的Java代碼:

Sign.java

 

 

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;

import javax.xml.bind.DatatypeConverter;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.provider.JDKKeyPairGenerator;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PEMWriter;

class Sign {

  public static PrintStream out = System.out;
  public static PrintStream err = System.err;

  private static byte[] pubKeyData = null;

  public static void main(String[] args) throws Exception {
	  
    if(args.length < 4) {
      err.println(Usage: java JavaSign    );
      System.exit(1);
    }
    
    File pemFile = new File(args[0]);
    File pubFile = new File(args[1]);
    File dataFile = new File(args[2]);
    
    if(!dataFile.exists()) {
    	err.println(Data File Does Not Exist);
    	System.exit(1);
    }
    
    Security.addProvider(new BouncyCastleProvider());
    KeyPair keys = null;
    
    if(!pemFile.exists()) {
    	
    	err.println(PEM File Does Not Exist. Generating.);
    	KeyPairGenerator r = KeyPairGenerator.getInstance(RSA);
    	
    	//keysize in bits is 2048
    	r.initialize(2048,new SecureRandom());
    	keys = r.generateKeyPair();
    	PEMWriter pemWriter = new PEMWriter(new FileWriter(pemFile));
    	pemWriter.writeObject(keys);
    	pemWriter.close(); //You must flush or close the file or else it will not save
    }
    else {
    	keys = (KeyPair) new PEMReader(new FileReader(pemFile)).readObject();
    }
    
    //read data file into signature instance
    FileInputStream fin = new FileInputStream(dataFile);
    byte[] data = new byte[(int) dataFile.length()];
    fin.read(data);
    fin.close();
    
    //Sign the data
    Signature sg = Signature.getInstance(SHA1withRSA);
    sg.initSign(keys.getPrivate());
    sg.update(data);
    
    //output base64 encoded binary signature 
    byte signBytes[] = sg.sign();
    
    fin = new FileInputStream(pubFile);
    pubKeyData = new byte[(int) pubFile.length()];
    fin.read(pubKeyData);
    fin.close();
    
    int len = pubKeyData.length;
    for (int i=0;i

 

同樣先編譯:

 

export CLASSPATH=.:bcprov-jdk15-140.jar
javac Sign.java 


 

再看看看如何生成簽名文件:

 

java JavaSign private.pem public.bin test.dat sign.bin

 

這裡的test.dat即是要校驗的數據,sign.bin為生成的簽名文件:

 

最後,就是如何使用公鑰和簽名文件進行校驗數據了:

來看下面的代碼:

 

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;

import javax.xml.bind.DatatypeConverter;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.provider.JDKKeyPairGenerator;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PEMWriter;

class Verify {

  public static PrintStream out = System.out;
  public static PrintStream err = System.err;

  private static byte[] pubKeyData = null;

  public static void main(String[] args) throws Exception {
	  
    if(args.length < 3) {
      err.println(Usage: java Verify    );
      System.exit(1);
    }
    
    File pubFile = new File(args[0]);

    
    FileInputStream fin = new FileInputStream(pubFile);
    pubKeyData = new byte[(int) pubFile.length()];
    fin.read(pubKeyData);
    fin.close();    

    out.println(verifytData:+verifyData(new File(args[1]),new File(args[2])));
  }
    
  public static boolean verifyData(File signFile,File dataFile) {
		if(!signFile.exists()) {
			return false;
		}

		FileInputStream in = null;
		try {
			in = new FileInputStream(signFile);
			byte[] signatureBytes = new byte[(int)signFile.length()];
			in.read(signatureBytes);
			in.close();

			in = new FileInputStream(dataFile);
			byte[] data = new byte[(int)dataFile.length()];
			in.read(data);
			in.close();

			if (!verify(pubKeyData,signatureBytes,data)) {
                return false;
			}
			
			return true;
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return false;
	}
  
  public static boolean verify(byte[] pubKeyBytes,byte[] signatureBytes,byte[] dataBytes) throws Exception {
	X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(pubKeyBytes);
	KeyFactory keyFactory = KeyFactory.getInstance(RSA);
	PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
	
	//load public key
    Signature sg = Signature.getInstance(SHA1withRSA);
    sg.initVerify(pubKey);
    
    sg.update(dataBytes);
    
    //validate signature
    if(sg.verify(signatureBytes)){
    	return true;
    }
    return false;	    
  }  
  

}


 

使用方法:

java Verify public.bin sign.bin test.dat

 

在使用的過程中,簽名文件一般是和數據打包在一起的,並且在校驗的時候要保證公鑰不會被篡改,要不然校驗就沒有意義了。


 

當然,這裡對RSA的加密原理並沒有討論,這方面網上有很多相關的資料。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved