rsa加密

一、java端java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;


public class RSAEncrypt {
private static final String DEFAULT_PUBLIC_KEY=
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChDzcjw/rWgFwnxunbKp7/4e8w" + "\r" +
"/UmXx2jk6qEEn69t6N2R1i/LmcyDT1xr/T2AHGOiXNQ5V8W4iCaaeNawi7aJaRht" + "\r" +
"Vx1uOH/2U378fscEESEG8XDqll0GCfB1/TjKI2aitVSzXOtRs8kYgGU78f7VmDNg" + "\r" +
"XIlk3gdhnzh+uoEQywIDAQAB" + "\r";

private static final String DEFAULT_PRIVATE_KEY=
"MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKEPNyPD+taAXCfG" + "\r" +
"6dsqnv/h7zD9SZfHaOTqoQSfr23o3ZHWL8uZzINPXGv9PYAcY6Jc1DlXxbiIJpp4" + "\r" +
"1rCLtolpGG1XHW44f/ZTfvx+xwQRIQbxcOqWXQYJ8HX9OMojZqK1VLNc61GzyRiA" + "\r" +
"ZTvx/tWYM2BciWTeB2GfOH66gRDLAgMBAAECgYBp4qTvoJKynuT3SbDJY/XwaEtm" + "\r" +
"u768SF9P0GlXrtwYuDWjAVue0VhBI9WxMWZTaVafkcP8hxX4QZqPh84td0zjcq3j" + "\r" +
"DLOegAFJkIorGzq5FyK7ydBoU1TLjFV459c8dTZMTu+LgsOTD11/V/Jr4NJxIudo" + "\r" +
"MBQ3c4cHmOoYv4uzkQJBANR+7Fc3e6oZgqTOesqPSPqljbsdF9E4x4eDFuOecCkJ" + "\r" +
"DvVLOOoAzvtHfAiUp+H3fk4hXRpALiNBEHiIdhIuX2UCQQDCCHiPHFd4gC58yyCM" + "\r" +
"6Leqkmoa+6YpfRb3oxykLBXcWx7DtbX+ayKy5OQmnkEG+MW8XB8wAdiUl0/tb6cQ" + "\r" +
"FaRvAkBhvP94Hk0DMDinFVHlWYJ3xy4pongSA8vCyMj+aSGtvjzjFnZXK4gIjBjA" + "\r" +
"2Z9ekDfIOBBawqp2DLdGuX2VXz8BAkByMuIh+KBSv76cnEDwLhfLQJlKgEnvqTvX" + "\r" +
"TB0TUw8avlaBAXW34/5sI+NUB1hmbgyTK/T/IFcEPXpBWLGO+e3pAkAGWLpnH0Zh" + "\r" +
"Fae7oAqkMAd3xCNY6ec180tAe57hZ6kS+SYLKwb4gGzYaCxc22vMtYksXHtUeamo" + "\r" +
"1NMLzI2ZfUoX" + "\r";

/**
* 私鑰
*/
private RSAPrivateKey privateKey;

/**
* 公鑰
*/
private RSAPublicKey publicKey;

/**
* 字節數據轉字符串專用集合
*/
private static final char[] HEX_CHAR= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};


/**
* 獲取私鑰
* @return 當前的私鑰對象
*/
public RSAPrivateKey getPrivateKey() {
return privateKey;
}

/**
* 獲取公鑰
* @return 當前的公鑰對象
*/
public RSAPublicKey getPublicKey() {
return publicKey;
}

/**
* 隨機生成密鑰對
*/
public void genKeyPair(){
KeyPairGenerator keyPairGen= null;
try {
keyPairGen= KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
keyPairGen.initialize(1024, new SecureRandom());
KeyPair keyPair= keyPairGen.generateKeyPair();
this.privateKey= (RSAPrivateKey) keyPair.getPrivate();
this.publicKey= (RSAPublicKey) keyPair.getPublic();
}

/**
* 從文件中輸入流中加載公鑰
* @param in 公鑰輸入流
* @throws Exception 加載公鑰時產生的異常
*/
public void loadPublicKey(InputStream in) throws Exception{
try {
BufferedReader br= new BufferedReader(new InputStreamReader(in));
String readLine= null;
StringBuilder sb= new StringBuilder();
while((readLine= br.readLine())!=null){
if(readLine.charAt(0)=='-'){
continue;
}else{
sb.append(readLine);
sb.append('\r');
}
}
loadPublicKey(sb.toString());
} catch (IOException e) {
throw new Exception("公鑰數據流讀取錯誤");
} catch (NullPointerException e) {
throw new Exception("公鑰輸入流爲空");
}
}


/**
* 從字符串中加載公鑰
* @param publicKeyStr 公鑰數據字符串
* @throws Exception 加載公鑰時產生的異常
*/
public void loadPublicKey(String publicKeyStr) throws Exception{
try {

byte[] buffer=BASE64Decoder.decode(publicKeyStr);
KeyFactory keyFactory= KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec= new X509EncodedKeySpec(buffer);
this.publicKey= (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
throw new Exception("無此算法");
} catch (InvalidKeySpecException e) {
throw new Exception("公鑰非法");
} catch (NullPointerException e) {
throw new Exception("公鑰數據爲空");
}
}

/**
* 從文件中加載私鑰
* @param keyFileName 私鑰文件名
* @return 是否成功
* @throws Exception
*/
public void loadPrivateKey(InputStream in) throws Exception{
try {
BufferedReader br= new BufferedReader(new InputStreamReader(in));
String readLine= null;
StringBuilder sb= new StringBuilder();
while((readLine= br.readLine())!=null){
if(readLine.charAt(0)=='-'){
continue;
}else{
sb.append(readLine);
sb.append('\r');
}
}
loadPrivateKey(sb.toString());
} catch (IOException e) {
throw new Exception("私鑰數據讀取錯誤");
} catch (NullPointerException e) {
throw new Exception("私鑰輸入流爲空");
}
}

public void loadPrivateKey(String privateKeyStr) throws Exception{
try {

byte[] buffer= BASE64Decoder.decode(privateKeyStr);
PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);
KeyFactory keyFactory= KeyFactory.getInstance("RSA");
this.privateKey= (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException e) {
throw new Exception("無此算法");
} catch (InvalidKeySpecException e) {
e.printStackTrace();
throw new Exception("私鑰非法");
} catch (NullPointerException e) {
throw new Exception("私鑰數據爲空");
}
}

/**
* 加密過程
* @param publicKey 公鑰
* @param plainTextData 明文數據
* @return
* @throws Exception 加密過程當中的異常信息
*/
public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception{
if(publicKey== null){
throw new Exception("加密公鑰爲空, 請設置");
}
Cipher cipher= null;
try {
cipher= Cipher.getInstance("RSA");//, new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] output= cipher.doFinal(plainTextData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new Exception("無此加密算法");
} catch (NoSuchPaddingException e) {
e.printStackTrace();
return null;
}catch (InvalidKeyException e) {
throw new Exception("加密公鑰非法,請檢查");
} catch (IllegalBlockSizeException e) {
throw new Exception("明文長度非法");
} catch (BadPaddingException e) {
throw new Exception("明文數據已損壞");
}
}

/**
* 解密過程
* @param privateKey 私鑰
* @param cipherData 密文數據
* @return 明文
* @throws Exception 解密過程當中的異常信息
*/
public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception{
if (privateKey== null){
throw new Exception("解密私鑰爲空, 請設置");
}
Cipher cipher= null;
try {
cipher= Cipher.getInstance("RSA");//, new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] output= cipher.doFinal(cipherData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new Exception("無此解密算法");
} catch (NoSuchPaddingException e) {
e.printStackTrace();
return null;
}catch (InvalidKeyException e) {
throw new Exception("解密私鑰非法,請檢查");
} catch (IllegalBlockSizeException e) {
throw new Exception("密文長度非法");
} catch (BadPaddingException e) {
throw new Exception("密文數據已損壞");
}
}


/**
* 字節數據轉十六進制字符串
* @param data 輸入數據
* @return 十六進制內容
*/
public static String byteArrayToString(byte[] data){
StringBuilder stringBuilder= new StringBuilder();
for (int i=0; i<data.length; i++){
//取出字節的高四位 做爲索引獲得相應的十六進制標識符 注意無符號右移
stringBuilder.append(HEX_CHAR[(data[i] & 0xf0)>>> 4]);
//取出字節的低四位 做爲索引獲得相應的十六進制標識符
stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
if (i<data.length-1){
stringBuilder.append(' ');
}
}
return stringBuilder.toString();
}


public static void main(String[] args){
RSAEncrypt rsaEncrypt= new RSAEncrypt();
//rsaEncrypt.genKeyPair();


//加載公鑰
try {
rsaEncrypt.loadPublicKey(RSAEncrypt.DEFAULT_PUBLIC_KEY);
System.out.println("加載公鑰成功");
} catch (Exception e) {
System.err.println(e.getMessage());
System.err.println("加載公鑰失敗");
}

//加載私鑰
try {
rsaEncrypt.loadPrivateKey(RSAEncrypt.DEFAULT_PRIVATE_KEY);
System.out.println("加載私鑰成功");
} catch (Exception e) {
System.err.println(e.getMessage());
System.err.println("加載私鑰失敗");
}

//測試字符串
String encryptStr= "abc";
System.out.println("私鑰長度:"+rsaEncrypt.getPrivateKey().toString().length());
System.out.println("公鑰長度:"+rsaEncrypt.getPublicKey().toString().length());
try {
//加密
byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), encryptStr.getBytes());


//解密
byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), cipher);



System.out.println("密文長度:"+ cipher.length);
System.out.println(RSAEncrypt.byteArrayToString(cipher));
System.out.println("明文長度:"+ plainText.length);
System.out.println(RSAEncrypt.byteArrayToString(plainText));
System.out.println(new String(plainText));
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}ios

二、客戶端算法

 

static SecKeyRef _public_key=nil;app

 

- (SecKeyRef) getPublicKey{ // 從公鑰證書文件中獲取到公鑰的SecKeyRef指針dom

    if(_public_key == nil){ide

        NSString *path=[[NSBundlemainBundle] pathForResource:@"public_key"ofType:@"der"];測試

        NSData *certificateData =[[NSData alloc] initWithContentsOfFile:path];ui

        SecCertificateRef myCertificate =nil;this

        myCertificate=SecCertificateCreateWithData(kCFAllocatorDefault,(__bridge CFDataRef)certificateData);編碼

        SecPolicyRef myPolicy =SecPolicyCreateBasicX509();

        SecTrustRef myTrust;

        OSStatus status = SecTrustCreateWithCertificates(myCertificate,nil,&myTrust);

        SecTrustResultType trustResult;

        if (status == noErr) {

            status = SecTrustEvaluate(myTrust, &trustResult);

        }

        _public_key = SecTrustCopyPublicKey(myTrust);

        CFRelease(myCertificate);

        CFRelease(myPolicy);

        CFRelease(myTrust);

    }

    return_public_key;

}

-(NSString *)RSAEncrypotoTheData:(NSString *)plainText

{

    

    SecKeyRef publicKey=nil;

    publicKey=[self getPublicKey];

    size_t cipherBufferSize = SecKeyGetBlockSize(publicKey);

    uint8_t *cipherBuffer = NULL;

    

    cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));

    memset((void *)cipherBuffer, 0*0, cipherBufferSize);

    

    NSData *plainTextBytes = [plainText dataUsingEncoding:NSUTF8StringEncoding];

    int blockSize = cipherBufferSize-11// 這個地方比較重要是加密問組長度

    int numBlock = (int)ceil([plainTextBytes length] / (double)blockSize);

    NSMutableData *encryptedData = [[NSMutableData alloc] init];

    for (int i=0; i<numBlock; i++) {

        int bufferSize = MIN(blockSize,[plainTextBytes length]-i*blockSize);

        NSData *buffer = [plainTextBytes subdataWithRange:NSMakeRange(i * blockSize, bufferSize)];

        OSStatus status = SecKeyEncrypt(publicKey,

                                        kSecPaddingPKCS1,

                                        (const uint8_t *)[buffer bytes],

                                        [buffer length],

                                        cipherBuffer,

                                        &cipherBufferSize);

        

        if (status == noErr)

        {

            NSData *encryptedBytes = [[NSData alloc]

                                       initWithBytes:(const void *)cipherBuffer

                                       length:cipherBufferSize] ;

            [encryptedData appendData:encryptedBytes];

        }

        else

        {

            return nil;

        }

    }

    if (cipherBuffer)

    {

        free(cipherBuffer);

    }

    NSString *encrypotoResult=[NSString stringWithFormat:@"%@",[GTMBase64 encodeData:encryptedData]];

    return [GTMBase64 stringByEncodingData:encryptedData];

}

 

三、公匙和私匙生成

(http://yuur369.iteye.com/blog/1769395)(http://blog.yorkgu.me/2011/10/27/rsa-in-ios-using-publick-key-generated-by-openssl/)

openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem

四、x509編碼轉換pkcs8

 

openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt

相關文章
相關標籤/搜索