Potrzebuję wygenerować klucz z łańcucha, tak, że zawsze mogę utworzyć ten sam klucz z tego samego ciągu. (W szczególności obiekt typu Key, dzięki czemu mogę go użyć do utworzenia Szyfrów po to, aby utworzyć SealedObject) Czy jest to możliwe w Javie i na jaką kombinację klas/metod powinienem się tym zwracać?Wygeneruj klucz ze sznurka?
Odpowiedz
Dla szyfrowania AES:
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal("Hello, World!".getBytes("UTF-8"));
// reinit cypher using param spec
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
Podobnie dla przestarzałe PBKDF1 i niepewny DES do komunikowania się z starszych systemów lub celów uczenia:
byte[] salt = {
(byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
(byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
};
int count = 20;
PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
cipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
SealedObject sealed = new SealedObject(object, cipher);
...
Należy pamiętać, że liczba iteracji jest zbyt niska także w ostatnim przykładzie.
Dzięki. Dla jasności, jeśli wykonałem to samo po stronie serwera z tym samym hasłem, wygenerowałoby to szyfr, który mógłby zostać użyty do odszyfrowania SealedObject? –
To prawda. Dopóki używasz tych samych parametrów i specyfikacji klawiszy, będziesz mieć ten sam klucz. –
To byłaby lepsza odpowiedź, gdybyś usunął pierwszą połowę. DES jest dziś całkowicie zepsuty i używanie go nawet jako przykładu jest niebezpieczne (ludzie mogą go kopiować, nie wiedząc, że jest to niebezpieczne). –
Można to osiągnąć poprzez szyfrowanie Java.
Najpierw trzeba dwa słoiki:
Oto pełna przykład jak Data Encryption Standard w Javie:
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import org.bouncycastle.util.encoders.Base64;
public class KeyGen {
private SecretKey key;
private Cipher ecipher;
private Cipher dcipher;
private static KeyGen keyGen;
private KeyGen() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException{
key = KeyGenerator.getInstance("DES").generateKey();
ecipher = Cipher.getInstance("DES");
dcipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
}
public static KeyGen getInstance() throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException {
if(keyGen == null) {
keyGen = new KeyGen();
}
return keyGen;
}
public String encrypt(String str) throws UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
byte[] utf8 = str.getBytes("UTF8");
byte[] enc = ecipher.doFinal(utf8);
return new String(Base64.encode(enc));
}
public String decrypt(String str) throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
byte[] dec = Base64.decode(str);
byte[] utf8 = dcipher.doFinal(dec);
return new String(utf8, "UTF8");
}
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
KeyGen keyGen = KeyGen.getInstance();
String string = "JOYMAA";
String enc = keyGen.encrypt(string);
System.out.println(enc);
String dec = keyGen.decrypt(enc);
System.out.println(dec);
}
}
Zastosowanie:
KeyGen keyGen = KeyGen.getInstance();
String string = "JOYMAA";
String enc = keyGen.encrypt(string);
System.out.println(enc);
String dec = keyGen.decrypt(enc);
System.out.println(dec);
Mam nadzieję, że to ci pomoże.
DES już nikomu nie pomoże ... –
Szyfrowanie trybu ECB nie jest również możliwe. Posiadanie klasy o nazwie 'KeyGen' wykonującej szyfrowanie/deszyfrowanie również nie daje wiele nadziei. –
Chcesz użyć do tego celu PBKDF2 lub bcrypt. Ten pierwszy jest szerzej stosowany w moim doświadczeniu. Wydaje się, na podstawie tego comment, że java obsługuje to.
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
nie będzie "hashCode()" dla ciebie? jeśli nie - dlaczego? – amit
http://en.wikipedia.org/wiki/Java_hashCode()#The_java.lang.String_hash_function – JProgrammer
Nie tak daleko, jak wiem, ponieważ próbuję utworzyć SealedObject w celu enkapsulacji obiektu do transmisji: Nie próbuję zamazywać ciąg tekstowy w haszyszu, próbuję utworzyć klucz (obiekt) –