Dekryptering C++ til Java (RSA/SHA1/3DES)
Jeg har en tekstfil, der er krypteret med c++ (Wincrypt.h) og jeg vil gerne dekryptere tekstfil med java (JCE). Der er brugt RSA som provider, SHA-1 til hashing samt 3DES til kryptering.Jeg har prøvet diverse løsninger men det er ikke lykkedes mig at dekryptere filen. Jeg har søgt information forskellige steder men er ikke blevet klogere - jeg har dog konstanteret at det muligvis har noget med længden på nøglerne (keys) at gøre.
Jeg har vedlagt c++ krypteringsalgoritme og java dekrypteringsalgortime.
Hvis du/I kan give svaret i brede termer er dette også ok.
[C++]
-----------------------------------------------------------------
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define ACTION_ENCRYPT 1
#define ACTION_DECRYPT 2
//-----------------------------------------------------------------------
bool Crypt(char * szSource,
char * szDestination,
char * szPassword,
int Operation);
void writelog(char *);
//-----------------------------------------------------------------------
bool Crypt(char * szSource, char * szDestination, char * szPassword, int Operation)
{
//-----------------------------------------------------------------------
const IN_BUFFER_SIZE = 2048;
const OUT_BUFFER_SIZE = IN_BUFFER_SIZE + 512;
//-----------------------------------------------------------------------
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTHASH hHash;
//-----------------------------------------------------------------------
HANDLE hSource, hDest;
//-----------------------------------------------------------------------
BYTE pbBuffer[OUT_BUFFER_SIZE];
bool bFinished;
DWORD dwByteCount;
DWORD dwBytesWritten;
//-----------------------------------------------------------------------
char Tek_buffer[1024];
char * Tek_ptr;
ULONG rc;
bool Ret_sw;
//-----------------------------------------------------------------------
Tek_ptr = Tek_buffer;
Ret_sw = true;
hSource = CreateFile(szSource,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hSource == INVALID_HANDLE_VALUE) {
rc = GetLastError();
sprintf(Tek_buffer, "E Return from open source file. rc = %1d", rc);
writelog( Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
hDest = CreateFile(szDestination,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hDest == INVALID_HANDLE_VALUE) {
rc = GetLastError();
sprintf(Tek_buffer, "E Return from open destination file. rc = %1d", rc);
writelog( Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
if(!CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,0))
{
rc = GetLastError();
if(rc == NTE_BAD_KEYSET)
{
if(!CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,CRYPT_NEWKEYSET)) {
rc = GetLastError();
sprintf(Tek_buffer, "E Acquire context newkeyset rc : %1d", rc);
writelog(Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
}
else {
sprintf(Tek_buffer, "E Acquire contex rc : %1d", rc);
writelog(Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
}
if(!CryptCreateHash(hCryptProv,CALG_SHA1,0,0,&hHash)) {
rc = GetLastError();
sprintf(Tek_buffer, "E Create HASH rc: %1d", rc);
writelog(Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
if(!CryptHashData(hHash,(BYTE *) szPassword,strlen(szPassword),0)) {
rc = GetLastError();
sprintf(Tek_buffer, "E add HASH data to object rc: %1d", rc);
writelog(Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
if(!CryptDeriveKey(hCryptProv,CALG_3DES,hHash,0,&hKey)) {
rc = GetLastError();
sprintf(Tek_buffer, "E Generate crypt. session key rc: %1d", rc);
writelog(Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
CryptDestroyHash(hHash);
hHash = 0;
if(Operation==ACTION_ENCRYPT)
{
do
{
rc = ReadFile(hSource,pbBuffer,IN_BUFFER_SIZE,&dwByteCount,NULL);
if (rc == 0) {
rc = GetLastError();
sprintf( Tek_buffer, "E Action encrypt read source rc = %1d", rc);
writelog(Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
bFinished = (dwByteCount < IN_BUFFER_SIZE);
if (!CryptEncrypt(hKey,0,bFinished,0,pbBuffer,&dwByteCount,OUT_BUFFER_SIZE)) {
rc = GetLastError();
sprintf(Tek_buffer, "E Function encrypt data rc: %1d", rc);
writelog(Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
rc = WriteFile(hDest,pbBuffer,dwByteCount,&dwBytesWritten,NULL);
if ( rc == 0 ) {
rc = GetLastError();
sprintf(Tek_buffer, "E Action decrypt write dest rc : %1d", rc);
writelog(Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
}while(!bFinished);
}
else if(Operation==ACTION_DECRYPT)
{
do
{
rc = ReadFile(hSource,pbBuffer,IN_BUFFER_SIZE,&dwByteCount,NULL);
if (rc == 0) {
rc = GetLastError();
sprintf( Tek_buffer, "E Action decrypt read source rc = %1d", rc);
writelog(Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
bFinished = (dwByteCount < IN_BUFFER_SIZE);
if (!CryptDecrypt(hKey,0,bFinished,0,pbBuffer,&dwByteCount)) {
rc = GetLastError();
sprintf(Tek_buffer, "E Function decrypt data rc: %1d", rc);
writelog(Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
rc = WriteFile(hDest,pbBuffer,dwByteCount,&dwBytesWritten,NULL);
if ( rc == 0 ) {
rc = GetLastError();
sprintf(Tek_buffer, "E Action decrypt write dest rc : %1d", rc);
writelog(Tek_ptr);
Ret_sw = false;
goto Clean_up;
}
} while(!bFinished);
}
else
return false;
Clean_up:
if(hSource)
CloseHandle(hSource);
if(hDest)
CloseHandle(hDest);
if(hKey)
CryptDestroyKey(hKey);
if(hHash)
CryptDestroyHash(hHash);
if(hCryptProv)
CryptReleaseContext(hCryptProv,0);
return Ret_sw;
}
[Java]
-----------------------------------------------------------------
import java.io.*;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.interfaces.*;
import javax.crypto.spec.*;
public class SHA3DESdecrypter {
public static final int DEFAULT_KEY_LENGTH = 24;
public static final int DEFAULT_MAC_LENGTH = 20;
public static final int DEFAULT_IV_LENGTH = 8;
public static void decrypt (String passphrase, String from, String to) throws Exception
{
byte [] dataTemp;
try
{
Security.addProvider( new com.sun.crypto.provider.SunJCE() );
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(passphrase.getBytes());
// DESedeKeySpec key = new DESedeKeySpec (md.digest());
// DESedeKeySpec key = new DESedeKeySpec (convertPasswordToKey(passphrase.getBytes()));
// SecretKeySpec DESedeKey = new SecretKeySpec (key.getKey(), "DESede");
byte[] iv = new byte[8];
Cipher cipher = getBlockCipherForDecryption(convertPasswordToKey(passphrase.getBytes()),iv);
InputStream is = new FileInputStream(from);
OutputStream os = new FileOutputStream(to);
byte[] b = new byte[10000];
int n;
while((n = is.read(b)) >= 0) {
byte[] b2;
if(n < b.length) {
b2 = cipher.doFinal(b, 0, n);
} else {
b2 = cipher.update(b, 0, n);
}
os.write(b2, 0, b2.length);
}
is.close();
os.close();
} catch (Exception e) {
throw e;
}
}
public static void main(String[] args) throws Exception
{
SHA3DESdecrypter.decrypt ("TEST","c:\\z.2","c:\\z.3");
}
private static byte[] convertPasswordToKey(byte[] password)
{
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] seed = md.digest(password);
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(seed);
byte[] rawkey = new byte[24];
random.nextBytes(rawkey);
return rawkey;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static Cipher getBlockCipherForDecryption(byte[] rawKey, byte[] iv)
{
try {
SecretKeyFactory keygen = SecretKeyFactory.getInstance("DESede");
DESedeKeySpec keyspec = new DESedeKeySpec(rawKey);
Key key = keygen.generateSecret(keyspec);
Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, key, ivspec, SecureRandom.getInstance("SHA1PRNG"));
return cipher;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}