java - Java 中的 DES 实现。无法获取明文

标签 java security encryption des

我正在研究一个使用 Java 内置库实现 DES 的简单示例。这是我的代码:

import it.sauronsoftware.base64.Base64;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


public class DES {

    public static void main(String [] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException
    {
        String msg="This is a secret message";
        byte [] msgBytes=msg.getBytes();        
        byte [] keyBytes  = {(byte)0xFE, (byte)0xDC, (byte)0xBA, (byte)0x98, (byte)0x76, (byte)0x54, (byte)0x32, (byte)0x10};
        SecretKeySpec myDesKey = new SecretKeySpec(keyBytes, "DES");

        //to encrypt a message
        String cipher=encryptMsg(msgBytes, myDesKey);

        //to decrypt a message
        String plain = decryptMsg(cipher.getBytes(), myDesKey);

        System.out.println("Original Message: "+ msg);
        System.out.println("Encrypted Message: "+ cipher);
        System.out.println("Decrypted Message: "+ plain);

    } //end main

    //encryption function
    public static String encryptMsg(byte [] msgBytes, SecretKey myDesKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
    {
        Cipher desCipher;
        // Create the cipher 
        desCipher = Cipher.getInstance("DES/ECB/NoPadding");
        desCipher.init(Cipher.ENCRYPT_MODE, myDesKey);
        byte[] textEncrypted = desCipher.doFinal(msgBytes);

        // converts to base64 for easier display.
        byte[] base64Cipher = Base64.encode(textEncrypted);
        return new String(base64Cipher);
    } //end encryptMsg

    public static String decryptMsg(byte [] cipherBytes, SecretKey myDesKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
    {
        Cipher desCipher; 
        desCipher = Cipher.getInstance("DES/ECB/NoPadding");
        desCipher.init(Cipher.DECRYPT_MODE, myDesKey);
        byte[] textDecrypted=desCipher.doFinal(cipherBytes);

        // converts to base64 for easier display.
        byte[] base64Plain = Base64.encode(textDecrypted);
        return new String(base64Plain);
    } //end decryptMsg
} //end class

我得到的输出是:

Original Message: This is a secret message
Encrypted Message: hNFgTAoz2TN9f6FcLdbjnEBe5DrsU4sm
Decrypted Message: RFdk1JK0gG0vv2zndHueS9rRe0Oux44ACGObsRHQ+4E=

我需要我的 key 是固定(不是随机)值。这就是为什么我一开始就把它定义为字节数组。

我的问题是我的解密函数没有返回原始消息。这意味着代码存在问题,并且可能加密不正确。我对编码问题表示怀疑,因为加密/解密非常简单。你能指出我的代码中的问题吗?

编辑: 在解密过程中,我按照评论之一的建议将 encode 更改为 decode。那是行不通的。我得到:

Exception in thread "main" java.lang.RuntimeException: Unexpected I/O error
    at it.sauronsoftware.base64.Base64.decode(Unknown Source)
    at DES.decryptMsg(DES.java:55)
    at DES.main(DES.java:25)
Caused by: java.io.IOException: Bad base64 stream
    at it.sauronsoftware.base64.Base64InputStream.acquire(Unknown Source)
    at it.sauronsoftware.base64.Base64InputStream.read(Unknown Source)
    at java.io.InputStream.read(Unknown Source)
    at java.io.InputStream.read(Unknown Source)
    at it.sauronsoftware.base64.Base64.copy(Unknown Source)
    at it.sauronsoftware.base64.Base64.decode(Unknown Source)
    ... 3 more

最佳答案

您没有解码原始消息的加密;您正在解码加密原始消息的 base64 编码

您不需要传递 cipher.getBytes(),而是需要 Base64.decode(cipher).getBytes(),或者让该方法接受 base64 字符串并在方法中处理解码。

此外,无需对解密内容进行 Base64 解码。它已经是原始编码了。换句话说,只需返回new String(textDecrypted)

<小时/>

您尝试执行的流程是:明文 -> 加密内容 -> base64 -> 加密内容 -> 明文。您正在执行的流程是文本 -> 加密内容 -> Base64 -> 解密的 Base64(废话) -> Base64(废话)

关于java - Java 中的 DES 实现。无法获取明文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19534916/

相关文章:

java - 直方图比较

java - 这是在服务中每 x 秒重复一次方法的正确方法吗?

mysql - 限制对 MySQL 中行子集的访问

asp.net - .ASPXAuth Cookie 在 session 期间发生变化

java - 简单地测试 Spring Boot 安全性

c - C 语言的维吉尼亚密码封装

android - 最新的 Android 模拟器 : HTTPS Network Issues - Chrome

java - 从 Android 应用程序搜索 images.google.com

java - 动态生成Testng.xlm来运行测试

Python 2 - 解密 Java 的 PBEWithMD5AndDES