Piszę małą aplikację do przesyłania plików, mniej więcej tak, aby dowiedzieć się więcej o programowych podstawach szyfrowania. Pomysł polega na wygenerowaniu klucza RSA, wymianie kluczy publicznych i wysłaniu AES iv and key over w celu dalszego odszyfrowania. Chcę zaszyfrowania klucza AES z kluczem publicznym odbiorcy RSA, tak:Szyfrowanie klucza AES z kluczem publicznym RSA
// encode the SecretKeySpec
private byte[] EncryptSecretKey()
{
Cipher cipher = null;
byte[] key = null;
try
{
cipher = Cipher.getInstance("RSA/ECB/NOPADDING");
// contact.getPublicKey returns a public key of type Key
cipher.init(Cipher.ENCRYPT_MODE, contact.getPublicKey());
// skey is the SecretKey used to encrypt the AES data
key = cipher.doFinal(skey.getEncoded());
}
catch(Exception e)
{
System.out.println ("exception encoding key: " + e.getMessage());
e.printStackTrace();
}
return key;
}
Następnie wypisać wartość klucza do odbiornika i odszyfrować go tak:
private SecretKey decryptAESKey(byte[] data)
{
SecretKey key = null;
PrivateKey privKey = null;
Cipher cipher = null;
System.out.println ("Data as hex: " + utility.asHex(data));
System.out.println ("data length: " + data.length);
try
{
// assume this loads our private key
privKey = (PrivateKey)utility.loadLocalKey("private.key", false);
cipher = Cipher.getInstance("RSA/ECB/NOPADDING");
cipher.init(Cipher.DECRYPT_MODE, privKey);
key = new SecretKeySpec(cipher.doFinal(data), "AES");
System.out.println ("Key decrypted, length is " + key.getEncoded().length);
System.out.println ("data: " + utility.asHex(key.getEncoded()));
}
catch(Exception e)
{
System.out.println ("exception decrypting the aes key: " + e.getMessage());
e.printStackTrace();
return null;
}
return key;
}
W konsoli , z drugiej strony, mam to jako wyjście:
read_bytes for key: 16
data length: 16
Data as hex: <hex string>
Key decrypted, length is 256
java.security.InvalidKeyException: Invalid AES key length: 256 bytes
Ponadto, jeśli tworzę tablicę bajtów o rozmiarze 16 i umieścić cipher.doFinal (dane) wyjście do niego, tablica jest pozornie przeskalowane do 256 bajty (.leng przynajmniej tak mówi). Dlaczego miałoby to być i co dalej robię niewłaściwie?
edit
Rozwiązałem to i pomyślałem, że pisać problem w przypadku, gdy ktoś prowadzi do tego. Problemem okazał się RSA/ECB/NOPADDING. Z jakiegoś dziwnego powodu zepsuło mi to stworzenie SecretKey, kiedy przekazałem go klientowi. To może mieć coś wspólnego z tym, jak generuję klawisze (używam getInstance ("RSA")), ale nie jestem do końca pewien.
hi-hat, proszę zamieścić swoje ** ** pełna odpowiedź jako odpowiedź zamiast edytowania go w swoim pytaniu (możesz nam powiedzieć, co problem był, a nie odpowiedź). Następnie możesz zaakceptować własną odpowiedź po pewnym czasie. Lub zaakceptuj mój, co wyjaśnia, dlaczego powinieneś używać '' RSA/ECB/PKCS1Padding "' zamiast '" RSA/ECB/NoPadding "' ... –
Pamiętaj, że powinieneś używać ochrony integralności (np. Podpisu) podczas tworzenia protokół internetowy, który wykonuje szyfrowanie. Nawet szyfrowanie RSA może być podatne na np. padding ataki oracle. Brak ochrony integralności jest częstym błędem, chociaż ten problem jest ograniczony, jeśli używasz PKCS # 1 v1.5 (implikowanego przez '" RSA/ECB/PKCS1Padding "'). –
Jako siderote, EBC rzadko jest dobrym trybem dla serwera. – CodesInChaos