Avatar billede kc230877 Nybegynder
21. december 2005 - 13:37 Der er 14 kommentarer og
1 løsning

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);
        }
    }
}
Avatar billede kc230877 Nybegynder
29. december 2005 - 21:52 #1
Der er ikke meget liv i dette spørgsmål...:-)

Hvis nogen har et eksempel med 3DES-kryptering, som virker med både java og c++ er det også velkommen.
Avatar billede kc230877 Nybegynder
02. januar 2006 - 09:31 #2
Jeg prøver en sidste gang...

Jeg mangler informationer/eksempler om (de-)kryptering fra c++ til java. I det ovenstående har jeg lagt mig fast på RSA/SHA1/3DES men andre algoritmer er også velkomne. Filerne krypteres med c++ og dekrypteres med java - gerne med "Wincrypt.h" og JCE fra Sun.
Avatar billede arne_v Ekspert
03. januar 2006 - 00:31 #3
Sådan et spørgsmål her er altså en tung omgang.

Men jeg har leget lidt.

Og fundet noget C/C++ DES og 3DES som er kompatibelt med JCE.
Avatar billede arne_v Ekspert
03. januar 2006 - 00:32 #4
Avatar billede arne_v Ekspert
03. januar 2006 - 00:33 #5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "des.h"

#define N 1000000

/*
*  arnedes e|d infile outfile key
*/
int main(int argc, char *argv[])
{
  FILE *infile,*outfile;
  char *buf;
  unsigned long key[16][2];
  int len,len2,i;
  buf=(char *)malloc(N);
  memset(buf,0,N);
  /* read fdrom file */
  infile=fopen(argv[2],"rb");
  len=fread(buf,1,N,infile);
  fclose(infile);
  if(strcmp(argv[1],"e")==0)
  {
      /* encrypt */
      deskey(key,argv[4],0);
      len2=(len/8+1)*8;
      for(i=len;i<len2;i++) buf[i]=(len2-len);
      for(i=0;i<len2;i=i+8) des(key,buf+i);
  }
  else if(strcmp(argv[1],"d")==0)
  {
      /* decrypt */
      deskey(key,argv[4],1);
      for(i=0;i<len;i=i+8) des(key,buf+i);
      len2=len-buf[len-1];
  }
  /* write to file */
  outfile=fopen(argv[3],"wb");
  fwrite(buf,1,len2,outfile);
  fclose(outfile);
  return 0;
}
Avatar billede arne_v Ekspert
03. januar 2006 - 00:33 #6
gcc gensp.c -o gensp.exe
gensp c > dessp.c
gcc arnedes.c desport.c deskey.c dessp.c -o arnedes.exe
arnedes e ..\a.txt ..\b.txt 12345678
arnedes d ..\b.txt ..\c.txt 12345678
Avatar billede arne_v Ekspert
03. januar 2006 - 00:33 #7
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "des.h"

#define N 1000000

/*
*  arnedes3 e|d infile outfile key
*/
int main(int argc, char *argv[])
{
  FILE *infile,*outfile;
  char *buf;
  DES3_KS key;
  int len,len2,i;
  buf=(char *)malloc(N);
  memset(buf,0,N);
  /* read fdrom file */
  infile=fopen(argv[2],"rb");
  len=fread(buf,1,N,infile);
  fclose(infile);
  if(strcmp(argv[1],"e")==0)
  {
      /* encrypt */
      des3key(key,argv[4],0);
      len2=(len/8+1)*8;
      for(i=len;i<len2;i++) buf[i]=(len2-len);
      for(i=0;i<len2;i=i+8) des3(key,buf+i);
  }
  else if(strcmp(argv[1],"d")==0)
  {
      /* decrypt */
      des3key(key,argv[4],1);
      for(i=0;i<len;i=i+8) des3(key,buf+i);
      len2=len-buf[len-1];
  }
  /* write to file */
  outfile=fopen(argv[3],"wb");
  fwrite(buf,1,len2,outfile);
  fclose(outfile);
  return 0;
}
Avatar billede arne_v Ekspert
03. januar 2006 - 00:34 #8
gcc gensp.c -o gensp.exe
gensp c > dessp.c
gcc arnedes3.c des3port.c deskey.c dessp.c -o arnedes3.exe
arnedes3 e ..\a3.txt ..\b3.txt 123456789012345678901234
arnedes3 d ..\b3.txt ..\c3.txt 123456789012345678901234
Avatar billede arne_v Ekspert
03. januar 2006 - 00:34 #9
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class ArneDES {
    private final static int N = 1000000;
    public static void main(String[] args) throws Exception {
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
        Cipher crypt = Cipher.getInstance("DES/ECB/PKCS5Padding");
        SecretKey key = new SecretKeySpec(args[3].getBytes(), "DES");
        byte[] buf = new byte[N];
        InputStream is = new FileInputStream(args[1]);
        int len = is.read(buf);
        is.close();
        if(args[0].equals("e")) {
            crypt.init(Cipher.ENCRYPT_MODE, key);
            buf = crypt.doFinal(buf, 0, len);
           
        }
        if(args[0].equals("d")) {
            crypt.init(Cipher.DECRYPT_MODE, key);
            buf = crypt.doFinal(buf, 0, len);
        }
        OutputStream os = new FileOutputStream(args[2]);
        os.write(buf);
        os.close();
    }
}
Avatar billede arne_v Ekspert
03. januar 2006 - 00:35 #10
javac ArneDES.java
java ArneDES e aj.txt bj.txt 12345678
java ArneDES d bj.txt cj.txt 12345678
Avatar billede arne_v Ekspert
03. januar 2006 - 00:35 #11
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class ArneDES3 {
    private final static int N = 1000000;
    public static void main(String[] args) throws Exception {
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
        Cipher crypt = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        SecretKey key = new SecretKeySpec(args[3].getBytes(), "DESede");
        byte[] buf = new byte[N];
        InputStream is = new FileInputStream(args[1]);
        int len = is.read(buf);
        is.close();
        if(args[0].equals("e")) {
            crypt.init(Cipher.ENCRYPT_MODE, key);
            buf = crypt.doFinal(buf, 0, len);
           
        }
        if(args[0].equals("d")) {
            crypt.init(Cipher.DECRYPT_MODE, key);
            buf = crypt.doFinal(buf, 0, len);
        }
        OutputStream os = new FileOutputStream(args[2]);
        os.write(buf);
        os.close();
    }
}
Avatar billede arne_v Ekspert
03. januar 2006 - 00:35 #12
javac ArneDES3.java
java ArneDES3 e a3j.txt b3j.txt 123456789012345678901234
java ArneDES3 d b3j.txt c3j.txt 123456789012345678901234
Avatar billede arne_v Ekspert
03. januar 2006 - 00:36 #13
koden forudsætter at hele filen kan være i memory, men det kan du nemt
ændre på
Avatar billede kc230877 Nybegynder
03. januar 2006 - 11:35 #14
... og det virker perfekt :-)

Smid et svar og pointene er dine.

/Kenneth
Avatar billede arne_v Ekspert
03. januar 2006 - 13:30 #15
ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester