Avatar billede kc230877 Nybegynder
15. december 2005 - 10:09 Der er 3 kommentarer og
1 løsning

Problem med 3DES-dekryptering (JCE)

Jeg har lavet en lille java-applikation der (de)kryptere tekst-filer med java-packagen JCE vha. 3DES.

Applikationen krypterer tekst-filerne umiddelbart korrekt men kan ikke dekryptere filerne.

Forneden er fejlbesked, kildekode samt filen - "z.1" - der krypteres:

/Kenneth

-----------------------------------------------------------------
[Fejlbesked]

Exception in thread "main" java.security.InvalidKeyException: requires PBE param
eters
        at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineInit(DashoA12275
)
        at javax.crypto.Cipher.a(DashoA12275)
        at javax.crypto.Cipher.a(DashoA12275)
        at javax.crypto.Cipher.init(DashoA12275)
        at javax.crypto.Cipher.init(DashoA12275)
        at TripleDES.crypt(TripleDES.java:20)
        at TripleDES.decrypt(TripleDES.java:45)
        at TripleDES.main(TripleDES.java:49)
Caused by: java.security.InvalidAlgorithmParameterException: Parameters missing
        at com.sun.crypto.provider.SunJCE_ae.a(DashoA12275)
        at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineInit(DashoA12275
)
        ... 8 more

-----------------------------------------------------------------
[Kildekode]

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Security;
import javax.crypto.*;
import javax.crypto.spec.*;

public class TripleDES {

    private static void crypt(int mode, String fromname, String toname, String key) throws Exception {
    Security.addProvider(new com.sun.crypto.provider.SunJCE());

    PBEKeySpec sPBEKey = new PBEKeySpec(key.toCharArray());
    SecretKeyFactory sKeyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndTripleDES");
    SecretKey myTripleDesKey = sKeyFactory.generateSecret(sPBEKey);

    Cipher cipher = Cipher.getInstance(myTripleDesKey.getAlgorithm());

    cipher.init(mode,myTripleDesKey);

    InputStream is = new FileInputStream(fromname);
    OutputStream os = new FileOutputStream(toname);
    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); 
        System.out.println(n + " " + b2.length);
    }
    is.close();
    os.close();
    }

    public static void encrypt(String fromname, String toname, String key) throws Exception {
    crypt(Cipher.ENCRYPT_MODE, fromname, toname, key);
    }

    public static void decrypt(String fromname, String toname, String key) throws Exception {
    crypt(Cipher.DECRYPT_MODE, fromname, toname, key);
    }
    public static void main(String[] args) throws Exception {
    encrypt("C:\\z.1", "C:\\z.2", "Top hemmeligt kodeord");
    decrypt("C:\\z.2", "C:\\z.3", "Top hemmeligt kodeord");
    }
}

-----------------------------------------------------------------
[Filen "z.1"]

test
test1

-----------------------------------------------------------------
Avatar billede kc230877 Nybegynder
15. december 2005 - 14:15 #1
Efter at have arbejde på koden hele eftermiddagen er løsningen fundet!

Jeg har valgt en anden algoritme, der skulle være synonym med "PBEWithMD5AndTripleDES". Desuden skal key'en hashes med SHA1.

Her er resultatet:

-------------------------------------------------------------------------------------

import java.io.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.*;
import java.security.*;

public class TripleDES {

    private static void crypt(int mode, String fromname, String toname, String key) throws Exception {
    Security.addProvider(new com.sun.crypto.provider.SunJCE());

    byte[] bkey = new byte[24];

    getKeyedDigest(bkey,key.getBytes("UTF-8"));

    SecretKeySpec secretKey = new SecretKeySpec(bkey,"DESede");

    Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");

    cipher.init(mode,secretKey);

    InputStream is = new FileInputStream(fromname);
    OutputStream os = new FileOutputStream(toname);

    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); 
        System.out.println(n + " " + b2.length);
    }

    is.close();
    os.close();
    }

    public static void encrypt(String fromname, String toname, String key) throws Exception {
      crypt(Cipher.ENCRYPT_MODE, fromname, toname, key);
    }

    public static void decrypt(String fromname, String toname, String key) throws Exception {
      crypt(Cipher.DECRYPT_MODE, fromname, toname, key);
    }
    public static void main(String[] args) throws Exception {
      encrypt("C:\\z.1", "C:\\z.2", "philip");
      decrypt("C:\\z.2", "C:\\z.3", "philip");
    }


    public static byte[] getKeyedDigest(byte[] buffer, byte[] key) {
        try {
            MessageDigest sha = MessageDigest.getInstance("SHA1");
            sha.update(buffer);
            return sha.digest(key);
        } catch (NoSuchAlgorithmException e) {
        }
        return null;
    }
}
Avatar billede kc230877 Nybegynder
16. december 2005 - 14:07 #2
- Dette er blot til hjælp for andre som sidder med samme problem -

Jeg har fundet en mere korrekt måde at hashe med SHA1 og kryptere med TripleDES (3DES).

Her er resultatet.

import java.io.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.*;
import java.security.*;

public class TripleDES {

    private static void crypt(int mode, String fromname, String toname, String key) throws Exception {
    Security.addProvider(new com.sun.crypto.provider.SunJCE());

    PBEKeySpec pbeKeySpec;
    PBEParameterSpec pbeParamSpec;
    SecretKeyFactory keyFac;

    byte[] salt = {
        (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
        (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
    };

    int count = 20;

    pbeParamSpec = new PBEParameterSpec(salt, count);

    pbeKeySpec = new PBEKeySpec(key.toCharArray());
    keyFac = SecretKeyFactory.getInstance("PBEWithSHA1AndDESede");
    SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

    Cipher cipher = Cipher.getInstance("PBEWithSHA1AndDESede");

    cipher.init(mode, pbeKey, pbeParamSpec);

    InputStream is = new FileInputStream(fromname);
    OutputStream os = new FileOutputStream(toname);

    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();
    }

    public static void encrypt(String fromname, String toname, String key) throws Exception {
      crypt(Cipher.ENCRYPT_MODE, fromname, toname, key);
    }

    public static void decrypt(String fromname, String toname, String key) throws Exception {
      crypt(Cipher.DECRYPT_MODE, fromname, toname, key);
    }
    public static void main(String[] args) throws Exception {
      encrypt("C:\\hemmeligfil.csv", "C:\\z.2", "philip");
      decrypt("C:\\z.2", "C:\\z.3", "philip");
    }
}
Avatar billede kc230877 Nybegynder
19. december 2005 - 13:14 #3
Er der nogen der kender noget godt litteratur/tutorial om kryptering - ikke nødvendigvis kun om SHA1 og 3DES. Også gerne om provider'ere af algortimerne?
Avatar billede kc230877 Nybegynder
21. december 2005 - 13:24 #4
Lukker
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