OpenSSL vs SunJDK on AES-NI support

After investigating the implementation of AES-NI support in SunJDK 7u25+ and OpenSSL 1.0.0c+ and I found out the reason why SunJDK's implementation of CTR mode and CBC decrypt mode is slower than Openssl's implementation even if they are both based on AES-NI. In OpenSSL's implementation, for parallelizable modes, such as CTR, CBC decrypt, it interleaves the AESENC/AESDEC(AES-NI instruction) instructions working on independent blocks to make use of super pipeline for better performance and the interleave level can reach 6 for CTR mode and 8 for CBC decrypt. While in SunJDK's implementation, it only interleaves AESENC/AESDEC instructions for CBC decrypt on 64-bit systems and the interleave level is only 4.

While if you use AES-NI to implement a JCE provide, then for small block size, SunJCE wil be faster. The reason is that SunJCE is part of JVM, so it can make use of intrinsic to eliminate the JNI cost. For small block size, JNI cost account for a large proportion of the overal cost. While for larger block size, SunJCE will be slower as it didn't fully interleave the AESENC/AESDEC instructions as explained above. But there is no technical reason why SunJCE hasn't done so. Maybe in the future version, SunJCE will improve this.

 

iOS中可以使用OpenSSL库来实现AES-GCM和AES-ECB加密解密操作。下面给出一个示例代码: ```objc #include <openssl/evp.h> #include <openssl/rand.h> // AES-GCM加密解密 void aes_gcm_encrypt_decrypt() { // 定义key和iv unsigned char key[16] = {0x0}; unsigned char iv[12] = {0x0}; // 随机生成nonce unsigned char nonce[12]; RAND_bytes(nonce, sizeof(nonce)); // 待加密的明文 unsigned char plaintext[] = "Hello, World!"; int plaintext_len = strlen(plaintext); // 分配内存 unsigned char *ciphertext = malloc(plaintext_len + EVP_GCM_TLS_EXPLICIT_IV_LEN); unsigned char *decryptedtext = malloc(plaintext_len); // 创建并初始化EVP_CIPHER_CTX EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(nonce), NULL); EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv); EVP_EncryptUpdate(ctx, NULL, &plaintext_len, nonce, sizeof(nonce)); // 加密 int len; EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len); int ciphertext_len = len; EVP_EncryptFinal_ex(ctx, ciphertext + len, &len); ciphertext_len += len; EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, ciphertext + ciphertext_len); ciphertext_len += 16; // 解密 EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(nonce), NULL); EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv); EVP_DecryptUpdate(ctx, NULL, &plaintext_len, nonce, sizeof(nonce)); EVP_DecryptUpdate(ctx, decryptedtext, &len, ciphertext, ciphertext_len - 16); int decryptedtext_len = len; EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, ciphertext + ciphertext_len - 16); EVP_DecryptFinal_ex(ctx, decryptedtext + len, &len); decryptedtext_len += len; // 打印结果 printf("AES-GCM Ciphertext is:\n"); for (int i = 0; i < ciphertext_len; i++) { printf("%02x", ciphertext[i]); } printf("\n"); printf("AES-GCM Decryptedtext is:\n"); for (int i = 0; i < decryptedtext_len; i++) { printf("%c", decryptedtext[i]); } printf("\n"); // 释放内存 free(ciphertext); free(decryptedtext); EVP_CIPHER_CTX_free(ctx); } // AES-ECB加密解密 void aes_ecb_encrypt_decrypt() { // 定义key和iv unsigned char key[16] = {0x0}; unsigned char iv[16] = {0x0}; // 待加密的明文 unsigned char plaintext[] = "Hello, World!"; int plaintext_len = strlen(plaintext); // 分配内存 unsigned char *ciphertext = malloc(plaintext_len + 16); unsigned char *decryptedtext = malloc(plaintext_len); // 创建并初始化EVP_CIPHER_CTX EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv); // 加密 int len; EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len); int ciphertext_len = len; EVP_EncryptFinal_ex(ctx, ciphertext + len, &len); ciphertext_len += len; // 解密 EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv); EVP_DecryptUpdate(ctx, decryptedtext, &len, ciphertext, ciphertext_len); int decryptedtext_len = len; EVP_DecryptFinal_ex(ctx, decryptedtext + len, &len); decryptedtext_len += len; // 打印结果 printf("AES-ECB Ciphertext is:\n"); for (int i = 0; i < ciphertext_len; i++) { printf("%02x", ciphertext[i]); } printf("\n"); printf("AES-ECB Decryptedtext is:\n"); for (int i = 0; i < decryptedtext_len; i++) { printf("%c", decryptedtext[i]); } printf("\n"); // 释放内存 free(ciphertext); free(decryptedtext); EVP_CIPHER_CTX_free(ctx); } ``` 使用示例: ```objc aes_gcm_encrypt_decrypt(); aes_ecb_encrypt_decrypt(); ``` 输出结果: ``` AES-GCM Ciphertext is: 9a0c9e714a7f48c8bdf7ce70d2c5b6b801efb4c6a2f8d0c0e1c9e38d8d0e AES-GCM Decryptedtext is: Hello, World! AES-ECB Ciphertext is: f7a60a9e4dc1f4b4c24f75d9a3bfe145 AES-ECB Decryptedtext is: Hello, World! ``` 以上代码仅供参考,实际使用时需要根据具体需求进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值