Ahoj.
Riesim problem so sifrovanim v Jave. Aby som popisal situaciu:
Existuje urcity program v C++ s openssl, ktory sifruje a desifruje
vstupny subor.
V principe robi to, ze si vygeneruje DES, ktorym zasifruje data a to DES
zasifruje nejakym
public RSA a pribali to k datam. Proste klasika.
K tomu existuje implementacia encryptora v Jave, ktory robi to iste.
Mam overene, ze decryptor v c++ si s tym poradi bez problemov.
Fragment encryptora:
// nageneruj des
KeyGenerator keygen = KeyGenerator.getInstance("DESede", "BC");
m_desKey = keygen.generateKey();
// zasifruj des public klucom a zapis na disk
JDKX509CertificateFactory f = new JDKX509CertificateFactory();
X509Certificate cert = (X509Certificate)
f.engineGenerateCertificate(pem_file);
Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
rsaCipher.init(Cipher.ENCRYPT_MODE, cert);
file.write(rsaCipher.doFinal(data)); // zapise 128 byte
... pridaj data a tak dalej ...
Ja som teraz naimplementoval decryptor v Jave ako protikus encryptora a
narazil som na nasledovny problem:
// citam zo suboru, z hlavicky som ziskal, ze zasifrovany DES ma 128 byte
byte[] zasifrovane_des = read(128);
// nacitam si z disku privatny kluc
KeyPair kp = readKeyPair(pem_na_disku, password);
PrivateKey pk = kp.getPrivate();
// inicializujem sifru
Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
// pouzil som to iste co v encoder
rsaCipher.init(Cipher.DECRYPT_MODE, pk);
// desifrujem zabaleny DES
// tu to vrati 24 byte, pokial som zasifroval java encoderom. Pokial som
zasifroval c++ encoderom, vrati to 32 byte.
// Logicky nasledne dalej v kode leti vynimka "key size greather than 24
byte".
// Finta je ale v tom, ze ked tych 32 byte pokusne orezem na 24, tak to
funguje.
byte[] desifrovane_des = rsaCipher.doFinal(zasifrovane_des);
// ziskam des z jeho binarnej reprezentacie
SecretKeySpec kspc = new SecretKeySpec(desifrovane_des, 0,
desifrovane_des.length, "DESede");
SecretKeyFactory skf = SecretKeyFactory.getInstance("DESede");
SecretKey des = skf.generateSecret(kspc);
// todo desifrujem
// pokial desifrujem data vytvorene c++ encoderom -->
java.security.InvalidKeyException: key size greater than 24 bytes
// pokial desifrujem data vytvorene java encoderom --> ok
Exception vyleti len v pripade, ze desifrujem data, ktore vytvoril c++
encoder. Pokial desifrujem
data, ktore som si sam zasifroval, zbehne to ok ( DES ma spravne 24 byte ).
Takisto c++ decoder nema problem desifrovat mnou zasifrovane data.
Chyba spociva v tom, ze pokial pracujem s datami z c++ encodera,
rsaCipher.doFinal() mi vrati 32 namiesto 24 byte.
Ked som ale natvrdo skusil tych 32 byte orezat na 24 byte, normalne to
zafungovalo.
V oboch pripadoch tym rsa dekodujem pole bajtov velke 128 byte.
To vo mne evokuje dojem, ako keby c++ encoder pouzival iny padding alebo
nieco v tom zmysle. Zaroven ma ale zaraza, ze
c++ decoder nema problem s mnou zasifrovanymi datami.
Pokusne som si dal v oboch pripadoch vypisovat veci ako getAlgorythm(),
getFormat() a podobne.
Boli vzdy identicke.
Zatial som to v rychlosti vyriesil prasackym orezom na 24 byte, ale
chcem tomu prist na klb.
( Ono je ale mozne, ze to orezava aj ten povodny c++ decoder a ja o tom
vlastne ani neviem, pripadne to openssl riesi za neho).
Nejaky napad kam mam hrabnut aby som tomu prisiel na klb?
--
Diky
D