java - openssl 的 "aes-256-cfb"的 Java 名称是什么?

标签 java node.js encryption openssl cryptography

我正在使用 openssl 的 aes-256-cfb 算法(来自 NodeJS 的加密模块)。

虽然 NodeJS 和 Java 代码都成功加密和解密数据,但密文不同,即使 iv、 key 和明文都相同。

openssl/NodeJS cipherText:
05c2aad7bac42ed0846e9a52ce73df9ff9d7ff914feea49fed27d55ad690782a43107914c1b307ec92753227728c95b8e59c546d

Java cipherText: 
05C2AAD7BAC42ED084739340D47CEC9F03D8E94AC7B1E11A56A6654F76AD2C8076BCA162303E39B44D043732E98FDD28C52D

我猜测 openssl 的 aes-256-cfb 会转换为 Java 的 AES/CFB/NoPadding

密文都共享相同的初始 9 个字节,这很奇怪 - 如果使用的通用模式存在一些差异,我本希望它们共享前 16 个字节。 (希望“共模”是CFB/CBC/CTR/等的统称)

  • Java 的 AES/CFB/NoPadding 是 OpenSSL aes-256-cfb 的正确翻译吗?
  • 公共(public)前九个字节的存在是否意味着 Java 的 AES/CFB/NoPadding 至少使用 AES256,而不是 AES128?
  • 如果是这样,还有什么可能导致不同的密文?

测试用例如下:

OpenSSL/NodeJS:

var assert = require('assert');
var crypto = require('crypto');

describe('crypto', function() {
  it('should work', function () {
    var plainText = new Buffer('a secret plainText which has more than sixteen bytes');
    var key = new Buffer('fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210', 'hex');
    var iv = new Buffer('0123456789abcdef0123456789abcdef', 'hex');      

    var cipher = crypto.createCipheriv('aes-256-cfb', key, iv);
    var decipher = crypto.createDecipheriv('aes-256-cfb', key, iv);

    var cipherText = cipher.update(plainText);
    cipher.final(); // no need to use this value with cfb, it seems to always be empty?

    assert.equal(plainText.length, cipherText.length);

    assert.equal('05c2aad7bac42ed0846e9a52ce73df9ff9d7ff914feea49fed27d55ad690782a43107914c1b307ec92753227728c95b8e59c546d', cipherText.toString('hex'));

    var deciphered = decipher.update(cipherText);
    decipher.final(); // no need to use value this with cfb, it seems to always be empty?

    assert.equal(plainText, deciphered.toString('utf8'));
  });
});

Java/Android:

import android.test.InstrumentationTestCase;

import com.google.protobuf.ByteString;
import bit.Twiddling;

import java.security.AlgorithmParameters;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class CryptoTest extends InstrumentationTestCase {

    public void test_encrypt_and_decrypt() throws Exception {
        byte[] plainText = "a secret message which has more than sixteen bytes".getBytes();
        byte[] key = Twiddling.hexStringBEToBytes("fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210");
        byte[] iv = Twiddling.hexStringBEToBytes("0123456789abcdef0123456789abcdef");//0123456789abcdef0123456789abcdef");

        SecretKeySpec aesSecret = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
        Cipher decipher = Cipher.getInstance("AES/CFB/NoPadding");
        IvParameterSpec ivps = new IvParameterSpec(iv);
        assertEquals(16, iv.length);

        cipher.init(Cipher.ENCRYPT_MODE, aesSecret, ivps);
        byte[] cipherText = cipher.doFinal(plainText);

        assertEquals(plainText.length, cipherText.length);
        assertEquals("05C2AAD7BAC42ED084739340D47CEC9F03D8E94AC7B1E11A56A6654F76AD2C8076BCA162303E39B44D043732E98FDD28C52D", Twiddling.bytesToHexStringBE(cipherText));

        decipher.init(Cipher.DECRYPT_MODE, aesSecret, ivps);
        byte[] deciphered = decipher.doFinal(cipherText);

        assertEquals(new String(plainText), new String(deciphered));
    }
}

最佳答案

这是一个查找/替换错误 - 两个纯文本在前九个字节后不同。

OpenSSL 的 aes-256-cfb 的 Java 名称是 AES/CFB/NoPadding

关于java - openssl 的 "aes-256-cfb"的 Java 名称是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55915506/

相关文章:

java - 在 Java 中从 XML 获取子节点

java - 在什么情况下在 Java 中使用 float 优于 double ?

javascript - Node POST请求-接收数据

java - 重启服务器后JWT失效

java - 为什么我必须在此代码中使用额外的方法?

java - 如何将java数组列表转换为javascript数组?

node.js - 防止错误破坏/崩溃 gulp watch

node.js - 为什么 bin/www 文件在 express-generator 中没有扩展名?

encryption - RSA 加密中的 D/DP/DQ 参数

c# - TripleDES : Encrypt (.Net) - 解密 (CryptoJS)