问题
I have one password which needs to be travelled across network. So for the safety side I have encoded from transmitting end and doing decoding at receiving end.
But my friend still able to breach password on the network because he know that how I have encoded the password string.
Here is my code
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);
}
}
I want to know, Is that possible I could put some kind of password on my encoded string so that same password could be used by the one I want to decode the same string had sent over network in java ?
回答1:
It will likely help for you to first understand the difference between encoding and encrypting. Encoding describes a protocol for representing information. You've used base64, which encodes binary information into a subset of ASCII characters.
Encrypting is what you want. An encryption algorithm uses a key (your "password", with extra requirements) to manipulate the data in such a way that retrieving it without the key is computationally difficult (read: practically impossible).
Have a look at this excerpt below that demonstrates how to use AES in GCM mode to securely encrypt some data:
// 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
There is a lot going on in the code above compared to your original code, so I'll do my best to explain. The encryption algorithm we use, AES, expects a key with a length of 128, 192 or 256 bits. Java prohibits use of AES with a key size other than 128 bits due to legal reasons, so we are forced to use a 128 bit key here.
Because the password we want to use ("WizardsAreCool") is not 128 bits in length (it's actually 14 UTF8 characters long so 112 bits), we use PBKDF2, which is a key derivation function, to derive a key from our password that will be 128 bits long (hence the keySize
being 128).
PBKDF2 takes a few parameters here, including the password string, the salt (which isn't all that important when using PBKDF2 as a key derivation function, but we still apply good practice and make it random, as we should), and an iteration count, which determines how many times the underlying hash is applied to the password.
AES also takes a few parameters. The most important is the key. It also takes a nonce (since we are in GCM mode), which should be random also. The nonce is used to generate the encrypted bit-stream from the cipher, which is then XORed with our plaintext.
All in all, the example above is fit for production use and is completely secure.
来源:https://stackoverflow.com/questions/46986977/how-to-use-password-to-decode-a-string