加密方法如何工作?

How does the encryption methods work?

好吧,我正在阅读加密方法。我发现有3种类型。

  1. 哈希加密
  2. 对称方法
  3. 非对称形式

我不理解对称方法中的 hasing 加密和 AES 的某些部分。

散列加密面临的问题:: 我读到 -“一旦数据被加密,过程就无法逆转或解密”。 比我的问题是,如果您只能加密数据而不能解密数据,为什么有人会使用这种方法?还是我理解错了?

AES 面临的问题:: 下面是我找到的代码:

public class AES {

    private static SecretKeySpec secretKey;
    private static byte[] key;
    private static String decryptedString;
    private static String encryptedString;

    public static void setKey(String myKey) {

        MessageDigest sha = null;
        try {
            key = myKey.getBytes("UTF-8");
            System.out.println(key.length);
            sha = MessageDigest.getInstance("SHA-1");
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16); // use only first 128 bit
            System.out.println(key.length);
            System.out.println(new String(key, "UTF-8"));
            secretKey = new SecretKeySpec(key, "AES");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static String getDecryptedString() {
        return decryptedString;
    }

    public static void setDecryptedString(String decryptedString) {
        AES.decryptedString = decryptedString;
    }

    public static String getEncryptedString() {
        return encryptedString;
    }

    public static void setEncryptedString(String encryptedString) {
        AES.encryptedString = encryptedString;
    }

    public static String encrypt(String strToEncrypt) {
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            setEncryptedString(Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))));
        } catch (Exception e) {
            System.out.println("Error while encrypting: " + e.toString());
        }
        return null;
    }

    public static String decrypt(String strToDecrypt) {
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            setDecryptedString(new String(cipher.doFinal(Base64.decodeBase64(strToDecrypt))));
        } catch (Exception e) {
            System.out.println("Error while decrypting: " + e.toString());
        }
        return null;
    }
}

每个密码分别使用 128、192 和 256 位的密钥加密和解密 128 位块中的数据。

所以,在代码中:

key = Arrays.copyOf(key, 16);

它使用 128 位密钥,对吗?

但是加密和解密方法中的 base64 是什么?

public static String encrypt(String strToEncrypt) {
    try {
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        setEncryptedString(Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))));
    }
}

我不会查看您提供的代码,但会以最简单的方式回答您的问题。

如果我们想在某处保存密码并保持加密状态,我们会使用散列算法。你的问题仍然存在,我们为什么要这样做?情节略有转折,现在当我们需要使用散列密码进行身份验证时,我们不会反转散列,而是对输入的密码进行散列并将其与我们拥有的散列进行匹配。这为我们提供了一种以无法复制人类可读密码文本的方式将密码存储在某处的方法(哈希是不可逆的)。

希望这能消除您的困惑

Base64 是一种加密方法,用于将存储的许多数字数据标准化,并将文本转换为字节,简单来说,它是一种 class 将您存储的字符串转换为仅由 64 个不同字符组成的字符串(符号)及其组合。想了解更多base64,肯定google

哈希主要用于验证文本的正确性。

示例 1:

您有一个散列密码。一个人给你一个密码。你想检查他是否给了你正确的。因此,您使用相同的算法对他的密码进行哈希处理。如果您获得与您相同的哈希值,则密码正确。

散列的优点:您没有保留实际密码,因此如果有人侵入您的数据库,他们无法猜出真正的密码。

示例 2:

您正在下载一个大文件。您要确保通信没有错误,并且没有人将文件替换为可能包含恶意软件的其他文件。

编写该文件的供应商为您提供了文件的散列值,与文件分开。

下载文件后,运行 对其使用相同的哈希算法。如果您获得与供应商提供的相同的哈希值,您就知道您下载了正确的文件并且没有通信错误(可能性非常高)。

散列的优点:它在现实世界中几乎没有冲突,因此文件中的一个小改动极不可能得到相同的散列。

示例 3:

贵公司将员工使用的所有文档和文件都存储在磁盘上,不想存储重复项,因为这会浪费资源。因此,每当任何员工将文件存储在公司文档目录中时,都需要检查它是否与现有文件重复。

对于目录中的每个文件,您将其散列及其详细信息存储在一起。当员工添加新文件时,您 运行 该文件的哈希算法。如果散列与任何现有散列匹配,则它(很可能)是重复的。如果没有,就是一个新文件,可以保存。

散列的优点:比文件小很多。您可以比较短哈希字符串,而不是将整个文件与所有现有文件进行比较。


加密文本时使用 base64 的原因是加密算法是针对字节而不是文本。

您使用适当的字符编码(在本例中为 UTF-8)将原始文本转换为字节。但是在你运行加密算法之后,你得到的字节不一定符合任何标准的字符编码。那里可能有代表控制字符等的字节,或者是无效的 UTF-8 值。

因此,为了从中获取某种可读字符串,您可以使用 base64 - 它将加密的字节转换为即使在仅支持 ASCII 的旧环境中也可以使用的文本。

要解密文本,您首先必须使用 base64 算法将其转换回字节,然后您可以对其进行解密,并使用 UTF-8.

将解密后的字节转换回文本

真实文本➞[UTF-8]➞字节➞[CIPHER]➞加密字节➞[BASE64]➞加密文本

加密文本➞[BASE64]➞加密字节➞[DECIPHER]➞字节➞[UTF-8]➞真实文本

不要将此编码算法名称中的“64”与您在密码中使用的密钥和块的大小混淆。 “64”只是代表字节被翻译成 64 个可能的字符这一事实(加上 = 作为特殊填充符)。