首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android加密3DES ECB

Android加密3DES ECB
EN

Stack Overflow用户
提问于 2015-11-30 21:09:37
回答 2查看 2.1K关注 0票数 0

我需要使用由密码生成的自定义密钥对一些数据进行加密。

它必须是: 3DES密码模式: ECB填充模式:零

我找不到任何代码来做这件事。谁能给我举个例子?

我已经尝试过了,它显示了以下错误

代码语言:javascript
复制
ERROR: java.security.InvalidAlgorithmParameterException: expected IV length of 0


import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;

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

public class Encryption {

public static int MAX_KEY_LENGTH = DESedeKeySpec.DES_EDE_KEY_LEN;
private static String ENCRYPTION_KEY_TYPE = "DESede";
private static String ENCRYPTION_ALGORITHM = "DESede/ECB/PKCS5Padding";
private final SecretKeySpec keySpec;

public Encryption(String passphrase) {
    byte[] key;
    try {
        // get bytes representation of the password
        key = passphrase.getBytes("UTF8");
    } catch (UnsupportedEncodingException e) {
        throw new IllegalArgumentException(e);
    }

    key = padKeyToLength(key, MAX_KEY_LENGTH);
    keySpec = new SecretKeySpec(key, ENCRYPTION_KEY_TYPE);
}

// !!! - see post below
private byte[] padKeyToLength(byte[] key, int len) {
    byte[] newKey = new byte[len];
    System.arraycopy(key, 0, newKey, 0, Math.min(key.length, len));
    return newKey;
}

// standard stuff
public byte[] encrypt(byte[] unencrypted) throws GeneralSecurityException {
    return doCipher(unencrypted, Cipher.ENCRYPT_MODE);
}

public byte[] decrypt(byte[] encrypted) throws GeneralSecurityException {
    return doCipher(encrypted, Cipher.DECRYPT_MODE);
}

private byte[] doCipher(byte[] original, int mode) throws GeneralSecurityException {
    Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
    // IV = 0 is yet another issue, we'll ignore it here
    IvParameterSpec iv = new IvParameterSpec(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 });
    cipher.init(mode, keySpec, iv);
    return cipher.doFinal(original);
}
}

编辑:现在我有了这个,我将我的自定义密钥(密钥size=8)作为"passphrase“参数传递,我调用的php不接受加密的结果(这是不正确的)。

正确的加密是这个网站做的一个把算法“三重”和模式: ECB https://www.tools4noobs.com/online_tools/encrypt/

我还不知道我做错了什么。

代码语言:javascript
复制
public class Encryption {

public static int MAX_KEY_LENGTH = DESedeKeySpec.DES_EDE_KEY_LEN;
private static String ENCRYPTION_KEY_TYPE = "DESede";
private static String ENCRYPTION_ALGORITHM = "DESede/ECB/NoPadding";
private final SecretKeySpec keySpec; 

public Encryption(String passphrase) {
        byte[] key;
    try {
        // get bytes representation of the password
        key = passphrase.getBytes("UTF8");
    } catch (UnsupportedEncodingException e) {
        throw new IllegalArgumentException(e);
    }

    key = padKeyToLength(key, MAX_KEY_LENGTH);
    keySpec = new SecretKeySpec(key, ENCRYPTION_KEY_TYPE);
}


private byte[] padKeyToLength(byte[] key, int len) {
    byte[] newKey = new byte[len];
    System.arraycopy(key, 0, newKey, 0, Math.min(key.length, len));
    return newKey;
}

// standard stuff
public byte[] encrypt(byte[] unencrypted) throws GeneralSecurityException {
    return doCipher(unencrypted, Cipher.ENCRYPT_MODE);
}

public byte[] decrypt(byte[] encrypted) throws GeneralSecurityException {
    return doCipher(encrypted, Cipher.DECRYPT_MODE);
}

private byte[] doCipher(byte[] original, int mode) throws GeneralSecurityException {
    Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
    int bs = cipher.getBlockSize();
    byte[] padded = new byte[original.length + bs - original.length % bs];
    System.arraycopy(original, 0, padded, 0, original.length);
    cipher.init(mode, keySpec);
    return cipher.doFinal(padded);
}
EN

回答 2

Stack Overflow用户

发布于 2015-12-01 04:23:06

ECB模式不使用IV,这使得它成为确定性密码模式,这意味着它在语义上是不安全的。如果您仍然需要使用它,请删除IV作为参数:

代码语言:javascript
复制
int bs = cipher.getBlockSize();
byte[] padded = new byte[original.length + bs - original.length % bs];
System.arraycopy(original, 0, padded, 0, original.length);
cipher.init(mode, keySpec);
return cipher.doFinal(padded);

这将为您提供一条填充零的消息,然后可以对其进行加密。这是可行的,因为字节数组总是以零初始化。填充与BouncyCastle的ZeroPadding相同。如果您想像PHP的mcrypt那样进行零填充,那么可以使用

代码语言:javascript
复制
byte[] padded = new byte[original.length + (bs - original.length % bs) % bs];
票数 0
EN

Stack Overflow用户

发布于 2015-12-01 04:41:48

下面是我用3DES加密的代码示例。我也在我的secretKey中使用了Base64,但我想您会想出办法的。

代码语言:javascript
复制
public class KeywordsCipher {

private static final String PADDING = "DESede/ECB/NoPadding";
private static final String UTF_F8 = "UTF-8";
private static final String DE_SEDE = "DESede";
private String secretKey;

{...}

public String encrypt(String message, String secretKey) {

    byte[] cipherText = null;

    try {
        final byte[] secretBase64Key = Base64.decodeBase64(secretKey);
        final SecretKey key = new SecretKeySpec(secretBase64Key, DE_SEDE);
        final Cipher cipher = Cipher.getInstance(PADDING);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        final byte[] plainTextBytes = message.getBytes();
        cipherText = cipher.doFinal(plainTextBytes);
    } catch (NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | NoSuchPaddingException e) {
        throw new CipherException("Problem with encryption occured");
    }

    return Hex.encodeHexString(cipherText);
}

public CipherKeywordModel decrypt(String keyToDecrypt, String secretKey) {

    try {
        byte[] message = DatatypeConverter.parseHexBinary(keyToDecrypt);
        final byte[] secretBase64Key = Base64.decodeBase64(secretKey);
        final SecretKey key = new SecretKeySpec(secretBase64Key, DE_SEDE);
        final Cipher decipher = Cipher.getInstance(PADDING);
        decipher.init(Cipher.DECRYPT_MODE, key);
        final byte[] plainText = decipher.doFinal(message);
        String decryptedText = new String(plainText, UTF_F8);
    } catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | NoSuchPaddingException e) {
        throw new CipherException("Problem with encryption occured");
    }
    return decryptedText;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33999427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档