如何使用密码解码字符串?

我有一个密码需要通过网络传输。 因此,对于安全方面,我已经从发送端编码并在接收端进行解码。

但我的朋友仍然可以在网络上破解密码,因为他知道我如何编码密码字符串。

这是我的代码

package org; import java.util.Base64; public class EncodingString { public static void main(String[] args){ String str = "I'm Encoding then decoding"; byte[] bytesEncoded = Base64.getEncoder().encode(str.getBytes()); System.out.println(bytesEncoded); String EncodedPassword = new String(bytesEncoded); System.out.println("ecncoded value is " + EncodedPassword); byte[] valueDecoded= Base64.getDecoder().decode(bytesEncoded); System.out.println(valueDecoded); String DecodedPassword = new String(valueDecoded); System.out.println("Decoded value is " + DecodedPassword); } } 

我想知道,有可能我可以在我的编码字符串上加上某种密码,以便我可以使用相同的密码来解码在java中通过网络发送的相同字符串吗?

它可能有助于您首先了解编码加密之间的区别。 编码描述了用于表示信息的协议。 您已经使用了base64,它将二进制信息编码为ASCII字符的子集。

加密就是你想要的。 加密算法使用密钥(您的“密码”,具有额外要求)来操纵数据,使得在没有密钥的情况下检索数据在计算上是困难的(读取:几乎不可能)。

请看下面的摘录,演示如何在GCM模式下使用AES来安全地加密某些数据:

 // The plaintext to encrypt, and the password we want to use. String plaintext = "Hello, World!"; String password = "WizardsAreCool"; // Parameters for PBKDF2/AES. Using a higher iteration count // is better in production. int iterationCount = 25000; int keySize = 128; int tagSize = 128; int saltSize = 16; int nonceSize = 12; // We generate a random salt for PBKDF2. SecureRandom rng = new SecureRandom(); byte[] salt = new byte[saltSize]; rng.nextBytes(salt); // We derive a 128-bit key using PBKDF2 from the password, // as AES-128 expects a 128-bit key. We also use SHA256 instead // of SHA1 for the underlying hash. PBEKeySpec pwSpec = new PBEKeySpec(password.toCharArray(), salt, iterationCount, keySize); SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); byte[] key = keyFac.generateSecret(pwSpec).getEncoded(); // We convert the plaintext to binary and generate a 12-byte nonce for // GCM mode. byte[] rawData = plaintext.getBytes(StandardCharsets.UTF_8); byte[] nonce = new byte[nonceSize]; rng.nextBytes(nonce); // We define the cipher. Cipher aesGcm = Cipher.getInstance("AES/GCM/NoPadding"); GCMParameterSpec gcmSpec = new GCMParameterSpec(tagSize, nonce); aesGcm.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), gcmSpec); // We get the resulting ciphertext. byte[] encResult = aesGcm.doFinal(rawData); // We produce the final result by prepending the PBKDF2 salt and // the nonce. byte[] result = new byte[saltSize + nonceSize + encResult.length]; System.arraycopy(salt, 0, result, 0, saltSize); System.arraycopy(nonce, 0, result, saltSize, nonceSize); System.arraycopy(encResult, 0, result, saltSize + nonceSize, encResult.length); // Print the result as base64. byte[] b64Result = Base64.getEncoder().encode(result); System.out.println(new String(b64Result)); // Sample Output // C100zs91Ku/TbQw4Mgw7e95didsA1Vj5oHGeMitohnRaUGIB08+T6uESro4P2Gf7q/7moMbWTTNT 

与原始代码相比,上面的代码中有很多内容,所以我会尽力解释。 我们使用的加密算法AES需要一个长度为128,192或256位的密钥。 由于法律原因,Java禁止使用密钥大小不是128位的AES,因此我们不得不在此处使用128位密钥。

因为我们想要使用的密码(“WizardsAreCool”)长度不是128位(它实际上是14个UTF8字符长,所以是112位),我们使用PBKDF2,这是一个密钥派生函数 ,从我们的密码中导出一个密钥,长度为128位(因此keySize为128)。

PBKDF2在这里采用了一些参数,包括密码字符串,salt(当使用PBKDF2作为密钥派生函数时,这并不是那么重要,但是我们仍然应用良好实践并使其随机化,如我们所应)和迭代count,它确定将基础哈希应用于密码的次数。

AES也需要一些参数。 最重要的是关键。 它也需要一个随机数(因为我们处于GCM模式),它也应该是随机的。 nonce用于从密码生成加密的比特流,然后用我们的明文进行异或。

总而言之,上面的例子适合生产使用并且是完全安全的。