react-native java swift aes和rsa的加密

寫了幾個語言的aes和rsa加密,這裏記錄一下,加密的東西不太懂,這裏我只是按需求寫的方法,可能不適合有的需求
下面使我們提的需求:

第一步 實現AES-256-CBC加密函數 aes_encrypt

string data = "hasdfoe"
string iv = "tdMgL6ryu5ueIjKq"
string key = "RFzeuq4i27ZYpQReX5fIUnhJ8sf8semv"
string data_en = aes_encrypt(data, iv, key)

data_en = "eQa4f6kcxioyKZyN03icng==" 時爲正確結果

第二步 實現RSA基於OAEP的加密函數  rsa_encrypt   
(這裏的公鑰最好自己生成一個)
string publickey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0k2/rzX4jqoricv1S32rYNvK2KPgytqSsAEo0CsKHjsqymG1BgyI0adL93NgTXdMgKhzMgO6ML1mp6xQ8j+y3uHusDC1Iq73y4mCIqwSnt9x3FMpVMa7S8O6rYAVHERZI+FbHwrE2dqNEyQDojU2R2Yh8DKrukOW2NZ5XxkPf5pw5CxG8H/PVzusVAjI7JqskjBd7+9o0/1DKWu8kLSbXVqnLfZTui3WVGBb9B7PIY7B1YqzygZEPvJPv9BdAXKvKivcfGDJRDQ/fLOqAfp/k+soVaJN3tXY3F7RV3W2ytLt5tCnzT/2WxJFzCgyrjpWR+HN+A15ZlWAlAIzF4ELNQIDAQAB"

string data =  "tdMgL6ryu5ueIjKq RFzeuq4i27ZYpQReX5fIUnhJ8sf8semv"
string data_en = rsa_encrypt(data, publickey)

java

package yuku.alkitab.base.util;

import android.util.Base64;
import android.util.Log;

import com.google.common.io.BaseEncoding;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;


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

import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.datatype.DatatypeFactory;

import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;



/**
 * AES encryption and decryption
 * <p>
 * 1. key's length >= 16
 * 2. iv's length > 16
 * 3. "transformation": AES/CBC/PKCS5Padding
 * 4. iv=12(bytes) length=128(bits)
 * 5. iv=24(bytes) length=192(bits)
 * 6. iv=32(bytes) length=256(bits)
 * <p>
 * Created by Anter on 2018/4/11.
 */

public class EncryptUtil {
    public enum KeyEncoding {
        BASE64, BASE32, HEX
    }
    private static final String ALGORITHM_AES256 = "AES/CBC/PKCS5Padding";
    private static final String IV = "tdMgL6ryu5ueIjKq";
    private static final String KEY = "RFzeuq4i27ZYpQReX5fIUnhJ8sf8semv";

    private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0k2/rzX4jqoricv1S32rYNvK2KPgytqSsAEo0CsKHjsqymG1BgyI0adL93NgTXdMgKhzMgO6ML1mp6xQ8j+y3uHusDC1Iq73y4mCIqwSnt9x3FMpVMa7S8O6rYAVHERZI+FbHwrE2dqNEyQDojU2R2Yh8DKrukOW2NZ5XxkPf5pw5CxG8H/PVzusVAjI7JqskjBd7+9o0/1DKWu8kLSbXVqnLfZTui3WVGBb9B7PIY7B1YqzygZEPvJPv9BdAXKvKivcfGDJRDQ/fLOqAfp/k+soVaJN3tXY3F7RV3W2ytLt5tCnzT/2WxJFzCgyrjpWR+HN+A15ZlWAlAIzF4ELNQIDAQAB";
    private static final String RAS_OAEP = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";

    private final SecretKeySpec secretKeySpec;
    private final Cipher cipher;
    private IvParameterSpec iv;

    public EncryptUtil(){
        try {
            this.secretKeySpec = new SecretKeySpec(KEY.getBytes(), "AES");
            this.iv = new IvParameterSpec(IV.getBytes());
            this.cipher = Cipher.getInstance(ALGORITHM_AES256);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw Throwables.propagate(e);
        }
    }
    public EncryptUtil(byte[] key, byte[] iv) {
        try {
            this.secretKeySpec = new SecretKeySpec(key, "AES");
            this.iv = new IvParameterSpec(iv);
            this.cipher = Cipher.getInstance(ALGORITHM_AES256);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw Throwables.propagate(e);
        }
    }

    /**
     * Takes message and encrypts with Key
     *
     * @param message String
     * @return String Base64 encoded
     */
    public String aes_encrypt(String message) {
        try {
            Cipher cipher = getCipher(Cipher.ENCRYPT_MODE);

            byte[] encryptedTextBytes = cipher.doFinal(message.getBytes("UTF-8"));

            return BaseEncoding.base64().encode(encryptedTextBytes);
        } catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
            throw Throwables.propagate(e);
        }
    }


    /**
     * Base64 encoded version of key
     *
     * @return String
     */
    public String getKey() {
        return getKey(KeyEncoding.BASE64);
    }

    public String getKey(KeyEncoding encoding) {
        String result = null;
        switch (encoding) {
            case BASE64:
                result = BaseEncoding.base64().encode(secretKeySpec.getEncoded());
                break;
            case HEX:
                result = BaseEncoding.base16().encode(secretKeySpec.getEncoded());
                break;
            case BASE32:
                result = BaseEncoding.base32().encode(secretKeySpec.getEncoded());
                break;
        }

        return result;
    }

    private Cipher getCipher(int encryptMode) throws InvalidKeyException, InvalidAlgorithmParameterException {
        cipher.init(encryptMode, getSecretKeySpec(), iv);
        return cipher;
    }

    private SecretKeySpec getSecretKeySpec() {
        return secretKeySpec;
    }



    public  String rsa_encrypt(String txt)
    {
        String encoded = "";
        byte[] encrypted = null;
        try {
            byte[] publicBytes = Base64.decode(PUBLIC_KEY, Base64.DEFAULT);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey pubKey = keyFactory.generatePublic(keySpec);
            Cipher cipher = Cipher.getInstance(RAS_OAEP); //or try with "RSA"
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            encrypted = cipher.doFinal(txt.getBytes());
            encoded = Base64.encodeToString(encrypted, Base64.DEFAULT);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return encoded;
    }
}

reactnative

react-native需要繼承幾個庫,我用的是node-forgereact-native-crypto
我這裏創建了兩個文件,一個是key.js一個是加密的方法文件EncrypUtil.js.
key.js,文件,這裏相關的常量字符串,我也是網上copy的方法,所以就沒做處理

export const publicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0k2/rzX4jqoricv1S32rYNvK2KPgytqSsAEo0CsKHjsqymG1BgyI0adL93NgTXdMgKhzMgO6ML1mp6xQ8j+y3uHusDC1Iq73y4mCIqwSnt9x3FMpVMa7S8O6rYAVHERZI+FbHwrE2dqNEyQDojU2R2Yh8DKrukOW2NZ5XxkPf5pw5CxG8H/PVzusVAjI7JqskjBd7+9o0/1DKWu8kLSbXVqnLfZTui3WVGBb9B7PIY7B1YqzygZEPvJPv9BdAXKvKivcfGDJRDQ/fLOqAfp/k+soVaJN3tXY3F7RV3W2ytLt5tCnzT/2WxJFzCgyrjpWR+HN+A15ZlWAlAIzF4ELNQIDAQAB
-----END PUBLIC KEY-----`;
export const AESKey = 'RFzeuq4i27ZYpQReX5fIUnhJ8sf8semv'
export const AESIV = 'tdMgL6ryu5ueIjKq'

EncrypUtil.js文件,主要的加密方法

import forge from "node-forge";
import CryptoJS from 'crypto-js';


const encodeURL = text => text.replace(/\+/g, "-").replace(/\//g, "_");

export const rsa_encrypt = (plainText, key) => {
  const publicKey = forge.pki.publicKeyFromPem(key);
  return encodeURL(
    forge.util.encode64(
      publicKey.encrypt(plainText, "RSA-OAEP")
    )
  );
};


export const aes_encrypt = (plainText,key,iv) => {
    let key1 = CryptoJS.enc.Utf8.parse(key); //16?
    let aesiv = CryptoJS.enc.Utf8.parse(iv);    
    let srcs = CryptoJS.enc.Utf8.parse(plainText);
    encrypted = CryptoJS.AES.encrypt(srcs, key1, {
        iv: aesiv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    return encrypted.toString()
}

使用

import { rsa_encrypt,aes_encrypt } from "../../utils/EncryptUtil";
import { AESKey,AESIV, publicKey } from "../../utils/keys";
    componentDidMount() {
        
        console.log('aeskey== '+aes_encrypt('hasdfoe',AESKey,AESIV))
        console.log('raskey== '+rsa_encrypt('tdMgL6ryu5ueIjKq RFzeuq4i27ZYpQReX5fIUnhJ8sf8semv',publicKey))

    }

swift

swift用到了兩個庫,CryptoSwiftSwiftyRSA,我用的是Carthage的方式集成的,具體的可以參考它們上面的介紹

import UIKit
import CryptoSwift
import SwiftyRSA

class EncryptUtil: NSObject {
    let aesKey = "RFzeuq4i27ZYpQReX5fIUnhJ8sf8semv"
    let aesIV = "tdMgL6ryu5ueIjKq"
    let publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0k2/rzX4jqoricv1S32rYNvK2KPgytqSsAEo0CsKHjsqymG1BgyI0adL93NgTXdMgKhzMgO6ML1mp6xQ8j+y3uHusDC1Iq73y4mCIqwSnt9x3FMpVMa7S8O6rYAVHERZI+FbHwrE2dqNEyQDojU2R2Yh8DKrukOW2NZ5XxkPf5pw5CxG8H/PVzusVAjI7JqskjBd7+9o0/1DKWu8kLSbXVqnLfZTui3WVGBb9B7PIY7B1YqzygZEPvJPv9BdAXKvKivcfGDJRDQ/fLOqAfp/k+soVaJN3tXY3F7RV3W2ytLt5tCnzT/2WxJFzCgyrjpWR+HN+A15ZlWAlAIzF4ELNQIDAQAB"
    
    func aes_encrypt(_ message: String) -> String {
        var ciphertextStr = ""
        do {
            let aes = try AES(key: Array(aesKey.utf8),blockMode: CBC(iv: Array(aesIV.utf8)), padding: .pkcs7) // aes128
            let ciphertext = try aes.encrypt(Array(message.utf8))
            ciphertextStr = ciphertext.toBase64()!
            } catch {
            
        }
        return ciphertextStr
    }
    func rsa_encrypt(_ message: String) -> String {
        var ciphertextStr = ""
        do {
            let publicKeyCode = try PublicKey(base64Encoded: publicKey)
            let clear = try ClearMessage(string: message, using: .utf8)
            let encrypted = try clear.encrypted(with: publicKeyCode, padding: .OAEP)
            // Then you can use:
            ciphertextStr = encrypted.base64String
        } catch {
            
        }
        return ciphertextStr
        
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章