写了几个语言的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)
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;
}
}
在react-native
需要继承几个库,我用的是node-forge 和react-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
用到了两个库,CryptoSwift和SwiftyRSA,我用的是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
}
}