三、算法代码实现
1、AES算法代码实现在Java版本中使用的是JDK自带的算法,描述了如何使用JDK的算法。
2、C语言版本是完整的算法代码,相较于引用openssl等体积小,移植也较为方便
3、针对经常涉及的Andriod开发,也给出了Java/Kotlin调用方法以及C语言版本的JNI调用示例
Java版本实现AES算法
Java/Kotlin版本在Java开发和安卓开发中只有Base64的编码和解码API有些差别,其它是相同的。
Java实现
public class AesUtil { private static String AES_MODE = "AES/CBC/PKCS7Padding"; private static String CIPHER = "AES"; private static String CHARSET = "UTF-8"; private static byte[] IV_BYTES = "efghefghefghefgh".getBytes(); private static SecretKeySpec generateKey(byte[] password) { return new SecretKeySpec(password, CIPHER); } public static String encrypt(byte[] password, String message) throws Exception { try { SecretKeySpec key = generateKey(password); byte[] cipherText = encrypt(key, IV_BYTES, message.getBytes()); return new String(Base64.encode(cipherText, Base64.NO_WRAP)); } catch (Exception e) { e.printStackTrace(); } return null; } public static byte[] encrypt(SecretKeySpec key, byte[] iv, byte[] message) throws Exception { Cipher cipher = Cipher.getInstance(AES_MODE, "BC"); IvParameterSpec ivSpec = new IvParameterSpec(iv); cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); return cipher.doFinal(message); } public static String decrypt(byte[] password,String base64EncodedCipherText) throws Exception{ try { SecretKeySpec key = generateKey(password); byte[] decodedCipherText = Base64.decode(base64EncodedCipherText.getBytes(), Base64.NO_WRAP); byte[] decryptedBytes = decrypt(key, IV_BYTES, decodedCipherText); return new String(decryptedBytes); } catch (Exception e) { e.printStackTrace(); } return null; } private static byte[] decrypt(SecretKeySpec key,byte[] iv,byte[] decodedCipherText) throws Exception{ Cipher cipher = Cipher.getInstance(AES_MODE); IvParameterSpec ivSpec = new IvParameterSpec(iv); cipher.init(Cipher.DECRYPT_MODE, key, ivSpec); return cipher.doFinal(decodedCipherText); } } //测试 public void testAESJava() throws Exception { System.out.println("测试AES Java版本"); byte[] password = {'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd',}; System.out.println("密码字符串形式:" + new String(password)); String encrypt = AesUtil.encrypt(password, "[35380100360174,89860321249940031491,202109301322170001,DEVICE_LOGIN,3,20210930132217,12,8@1@1@0@1@21]"); System.out.println("AES加密结果:" + encrypt); String decrypt = AesUtil.decrypt(password, encrypt); System.out.println("AES解密结果:" + decrypt); }
Kotlin版本
object AesCryptUtil { private const val AES_MODE = "AES/CBC/PKCS7Padding" private const val CHARSET = "UTF-8" private const val CIPHER = "AES" private const val HASH_ALGORITHM = "SHA-256" private val IV_BYTES = byteArrayOf('e'.toByte(), 'f'.toByte(), 'g'.toByte(), 'h'.toByte(), 'e'.toByte(), 'f'.toByte(), 'g'.toByte(), 'h'.toByte(), 'e'.toByte(), 'f'.toByte(), 'g'.toByte(), 'h'.toByte(), 'e'.toByte(), 'f'.toByte(), 'g'.toByte(), 'h'.toByte() ) @Throws(NoSuchAlgorithmException::class, UnsupportedEncodingException::class) private fun generateKey(password: ByteArray): SecretKeySpec { return SecretKeySpec(password, CIPHER) } @Throws(GeneralSecurityException::class) fun encrypt(password: String, message: String): String { try { val key = generateKey(password) val cipherText = encrypt(key, IV_BYTES, message.toByteArray(charset(CHARSET))) //NO_WRAP is important as was getting \n at the end return Base64Utils.encodeToString(cipherText) } catch (e: UnsupportedEncodingException) { throw GeneralSecurityException(e) } } @Throws(GeneralSecurityException::class) fun encrypt(password: ByteArray, message: String): String { try { val key = generateKey(password) val cipherText = encrypt(key, IV_BYTES, message.toByteArray()) // DDLog.info("cipherText=${cipherText.contentToString()}") for (b in cipherText) { val st = String.format("%02X", b) } //NO_WRAP is important as was getting \n at the end return String(Base64Utils.encode(cipherText)) } catch (e: UnsupportedEncodingException) { throw GeneralSecurityException(e) } } @Throws(GeneralSecurityException::class) fun encrypt(key: SecretKeySpec, iv: ByteArray, message: ByteArray): ByteArray { val cipher = Cipher.getInstance(AES_MODE, "BC") val ivSpec = IvParameterSpec(iv) cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec) return cipher.doFinal(message) } @Throws(GeneralSecurityException::class) fun decrypt(password: String, base64EncodedCipherText: String): String { try { val key = generateKey(password) val decodedCipherText = Base64Utils.decode(base64EncodedCipherText.toByteArray()) val decryptedBytes = decrypt(key, IV_BYTES, decodedCipherText) return String(decryptedBytes, charset(CHARSET)) } catch (e: UnsupportedEncodingException) { throw GeneralSecurityException(e) } } @Throws(GeneralSecurityException::class) fun decrypt(password: ByteArray, base64EncodedCipherText: String): String { try { val key = generateKey(password) val decodedCipherText = Base64Utils.decode(base64EncodedCipherText.toByteArray()) val decryptedBytes = decrypt(key, IV_BYTES, decodedCipherText) return String(decryptedBytes, charset(CHARSET)) } catch (e: UnsupportedEncodingException) { throw GeneralSecurityException(e) } } @Throws(GeneralSecurityException::class) fun decrypt(key: SecretKeySpec, iv: ByteArray, decodedCipherText: ByteArray): ByteArray { val cipher = Cipher.getInstance(AES_MODE) val ivSpec = IvParameterSpec(iv) cipher.init(Cipher.DECRYPT_MODE, key, ivSpec) return cipher.doFinal(decodedCipherText) } }
C/C++语言实现AES算法
C语言实现的AES算法,在windows的实现,更多代码请下载:
int testAESCBC_Smartcard() { std::string skey = "abcdabcdabcdabcd"; std::string siv = "efghefghefghefgh"; std::string pwd = "[35380100360174,89860321249940031491,202109301322170001,DEVICE_LOGIN,3,20210930132217,12,8@1@1@0@1@21]"; std::string encryptedText = aes::encrypt_cbc(pwd, skey, siv); std::cout << encryptedText << std::endl; pwd = aes::decrypt_cbc(encryptedText, skey, siv); std::cout << pwd << std::endl; return 0; }
C语言版本的JNI实现:
public class AESHelper { static { System.loadLibrary("FlyNative"); } public native static String helloJNI(); public native static String encodeAESCBC(String key, String iv, String message); public native static String decodeAESCBC(String key, String iv, String encodedText); }
JNIEXPORT jstring JNICALL Java_com_flyscale_testaes_AESHelper_encodeAESCBC (JNIEnv *jniEnv, jclass clazz, jstring key, jstring iv, jstring msg){ std::string encodedText = AESUtil::encryptAESCBC(JavaStringToString(jniEnv, key), JavaStringToString(jniEnv, iv), JavaStringToString(jniEnv, msg)); return StringToJavaString(jniEnv, encodedText); } JNIEXPORT jstring JNICALL Java_com_flyscale_testaes_AESHelper_decodeAESCBC (JNIEnv *jniEnv, jclass clazz, jstring key, jstring iv, jstring msg){ std::string decodedText = AESUtil::decryptAESCBC(JavaStringToString(jniEnv, key), JavaStringToString(jniEnv, iv), JavaStringToString(jniEnv, msg)); return StringToJavaString(jniEnv, decodedText); }