Tartalomjegyzék

< Java

Titkosítás Java nyelven

Szöveg titkosítása

Az alábbi programban egy szöveget titkosítok majd visszafejtem. A titkosító és visszafejtő kulcs egy bájt sorozat.

A következőkben a használható titkosító algoritmusokat és kulcsméreteket láthatjuk:

Algoritmus Kulcsméret
DES 56 bit
AES 128 bit
DESede 168 bit és 112 bit
RC2 128 bit
RC4 128 bit
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
 
class ap
{
        public static void main(String args[]) throws Exception
        {
		String Algoritmus = "AES";
		int Kulcsmeret = 128;
 
		KeyGenerator kgen = KeyGenerator.getInstance(Algoritmus);
		kgen.init(Kulcsmeret); //128 jó;  192 és 256 bites lehet, hogy nem elérhető
		SecretKey skey = kgen.generateKey();
		byte[] raw = skey.getEncoded();
 
		SecretKeySpec key = new SecretKeySpec(raw, Algoritmus);
 
               // A kulcs generálást magunk is megtehetjük (ekkor az eddigiek kihagyhatók):
               /* 
               SecretKeySpec key = new SecretKeySpec(new byte[] 
               {56,57,58,59,56,57,58,59,56,57,58,59,56,57,58,59  }, "AES");
                */
 
 
		System.out.println("Kulcsméret: " + key.getEncoded().length);
 
		Cipher c = Cipher.getInstance(Algoritmus);
                c.init(Cipher.ENCRYPT_MODE, key);
		byte[] titkosSzoveg = new byte[16];
 
		titkosSzoveg = c.doFinal("titkoső".getBytes("UTF-8"));
 
                System.out.println("Titkosítva: " + new String(titkosSzoveg));
 
 
		c.init(Cipher.DECRYPT_MODE, key);
		byte[] tisztaSzoveg = new byte[10];
 
		tisztaSzoveg = c.doFinal(titkosSzoveg);
 
		System.out.println("Visszafejtett: " + new String(tisztaSzoveg));
        }
}

Coder osztály készítése

Coder.java
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
 
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
 
public class Coder {
    public static String encrypt(String clearText, SecretKeySpec key) {
        String result = "";
        try {
            result = tryEncrypt(clearText, key);
        } catch (NoSuchAlgorithmException e) {
            System.err.println("Hiba! Nincs ilyen algoritmus!");
        }catch(NoSuchPaddingException e) {
            System.err.println("Hiba! Nincs ilyen kitöltő!");
        }catch(InvalidKeyException e) {
            System.err.println("Hiba! Érvénytelen kulcs!");
        }catch(UnsupportedEncodingException e) {
            System.err.println("Hiba! Nem támogatott kódolás!");
        }catch(IllegalBlockSizeException e) {
            System.out.println("Hiba! Illegális blokkméret!");
        }catch(BadPaddingException e) {
            System.err.println("Hiba! Rossz kitöltő!");
        }
        return result;
    }
 
    public static String tryEncrypt(String clearText, SecretKeySpec key) 
            throws 
                NoSuchAlgorithmException, 
                NoSuchPaddingException, 
                InvalidKeyException, 
                UnsupportedEncodingException, 
                IllegalBlockSizeException, 
                BadPaddingException {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] plainTextByteArray = clearText.getBytes("UTF-8");
        byte[] secretTextByteArray = cipher.doFinal(plainTextByteArray);
        String secretText = new String(Base64.getEncoder().encode(secretTextByteArray));
        return secretText;
    }    
 
    public static String decrypt(String secretText, SecretKeySpec key) {
        String result = "";
        try {
            result = tryDecrypt(secretText, key);
        } catch (NoSuchAlgorithmException e) {
            System.err.println("Hiba! Nincs ilyen algoritmus!");
        }catch(NoSuchPaddingException e) {
            System.err.println("Hiba! Nincs ilyen kitöltő!");
        }catch(InvalidKeyException e) {
            System.err.println("Hiba! Érvénytelen kulcs!");
        }catch(UnsupportedEncodingException e) {
            System.err.println("Hiba! Nem támogatott kódolás!");
        }catch(IllegalBlockSizeException e) {
            System.out.println("Hiba! Illegális blokkméret!");
        }catch(BadPaddingException e) {
            System.err.println("Hiba! Rossz kitöltő!");
        }
        return result;
    }    
    public static String tryDecrypt(String secretText, SecretKeySpec key) 
            throws 
                NoSuchAlgorithmException, 
                NoSuchPaddingException, 
                InvalidKeyException, 
                UnsupportedEncodingException, 
                IllegalBlockSizeException, 
                BadPaddingException {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] encryptedByteArray = Base64.getDecoder().decode(secretText);
        byte[] decryptedByteArray = cipher.doFinal(encryptedByteArray);
        String clearText = new String(decryptedByteArray, "UTF-8");
        return clearText;
    }
 
    public static SecretKeySpec generateKey() throws NoSuchAlgorithmException {
        SecretKeySpec key;
        String algoritmus = "AES";
        int kulcsmeret = 128;
        KeyGenerator keyGenerator = KeyGenerator.getInstance(algoritmus);
        keyGenerator.init(kulcsmeret);
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] raw = secretKey.getEncoded();
        key = new SecretKeySpec(raw, algoritmus);
        return key;
    }
 
}

Használat:

App.java
import javax.crypto.spec.SecretKeySpec;
 
public class App {
    public static void main(String[] args) throws Exception {
        System.out.println("--Titkostás--");
 
        SecretKeySpec key = Coder.generateKey();
 
        String secretText = Coder.encrypt("titok", key);
        System.out.println(secretText);
 
        String clearText = Coder.decrypt(secretText, key);
        System.out.println(clearText);
 
    }
}

Kulcsgenerálás másként

Coder.java
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
 
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
 
public class Coder {
    public static String encrypt(String clearText, Key key) {
        String result = "";
        try {
            result = tryEncrypt(clearText, key);
        } catch (NoSuchAlgorithmException e) {
            System.err.println("Hiba! Nincs ilyen algoritmus!");
        }catch(NoSuchPaddingException e) {
            System.err.println("Hiba! Nincs ilyen kitöltő!");
        }catch(InvalidKeyException e) {
            System.err.println("Hiba! Érvénytelen kulcs!");
        }catch(UnsupportedEncodingException e) {
            System.err.println("Hiba! Nem támogatott kódolás!");
        }catch(IllegalBlockSizeException e) {
            System.out.println("Hiba! Illegális blokkméret!");
        }catch(BadPaddingException e) {
            System.err.println("Hiba! Rossz kitöltő!");
        }
        return result;
    }
 
    public static String tryEncrypt(String clearText, Key key) 
            throws 
                NoSuchAlgorithmException, 
                NoSuchPaddingException, 
                InvalidKeyException, 
                UnsupportedEncodingException, 
                IllegalBlockSizeException, 
                BadPaddingException {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] plainTextByteArray = clearText.getBytes("UTF-8");
        byte[] secretTextByteArray = cipher.doFinal(plainTextByteArray);
        String secretText = new String(Base64.getEncoder().encode(secretTextByteArray));
        return secretText;
    }    
 
    public static String decrypt(String secretText, Key key) {
        String result = "";
        try {
            result = tryDecrypt(secretText, key);
        } catch (NoSuchAlgorithmException e) {
            System.err.println("Hiba! Nincs ilyen algoritmus!");
        }catch(NoSuchPaddingException e) {
            System.err.println("Hiba! Nincs ilyen kitöltő!");
        }catch(InvalidKeyException e) {
            System.err.println("Hiba! Érvénytelen kulcs!");
        }catch(UnsupportedEncodingException e) {
            System.err.println("Hiba! Nem támogatott kódolás!");
        }catch(IllegalBlockSizeException e) {
            System.out.println("Hiba! Illegális blokkméret!");
        }catch(BadPaddingException e) {
            System.err.println("Hiba! Rossz kitöltő!");
        }
        return result;
    }    
    public static String tryDecrypt(String secretText, Key key) 
            throws 
                NoSuchAlgorithmException, 
                NoSuchPaddingException, 
                InvalidKeyException, 
                UnsupportedEncodingException, 
                IllegalBlockSizeException, 
                BadPaddingException {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] encryptedByteArray = Base64.getDecoder().decode(secretText);
        byte[] decryptedByteArray = cipher.doFinal(encryptedByteArray);
        String clearText = new String(decryptedByteArray, "UTF-8");
        return clearText;
    }
 
    public static SecretKeySpec generateKey() throws NoSuchAlgorithmException {
        SecretKeySpec key;
        String algoritmus = "AES";
        int kulcsmeret = 128;
        KeyGenerator keyGenerator = KeyGenerator.getInstance(algoritmus);
        keyGenerator.init(kulcsmeret);
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] raw = secretKey.getEncoded();
        key = new SecretKeySpec(raw, algoritmus);
        return key;
    }
 
}

Használat:

App.java
import java.security.Key;
 
import javax.crypto.spec.SecretKeySpec;
 
public class App {
    public static void main(String[] args) throws Exception {
        System.out.println("--Titkostás--");
 
        String key = "1234567890123456"; // 128 bites kulcs
        Key aeskey = new SecretKeySpec(key.getBytes(), "AES");
 
 
        String secretText = Coder.encrypt("titok", aeskey);
        System.out.println(secretText);
 
        String clearText = Coder.decrypt(secretText, aeskey);
        System.out.println(clearText);
 
    }
}

Jelszó titkosítás

A jelszavakat csak egyirányú titkosítással szoktuk titkosítani, mivel a visszafejtés nem szükséges. A bekért jelszót lekódoljuk a tárolt jelszó algoritmusával. A két kódolt jelszót hasonlítom össze. Az ilyen egyirányú algoritmusokkal készült karaktersorozatot kivonatnak hívjuk, vagyis digest angolosan.

import java.security.*;
import java.io.*;
 
class md5
{
	public static void main(String args[]) throws IOException, NoSuchAlgorithmException 
	{
		System.out.println("Titkosítás egyirányba");
 
		// Lehetséges algoritmusok: SHA, MD5, SHA1 SHA-1, SHA-256, SHA-384, SHA-512
		MessageDigest md = MessageDigest.getInstance("SHA-256");
 
		byte[] sb = md.digest("baa".getBytes());		
		System.out.println(new String(sb));
 
		byte[] sa = md.digest("aaa".getBytes());		
		System.out.println(new String(sa));	
 
		System.in.read();
	}
}

Ez a program már lekódolja az eredmény viszont nem nyomtatható karaktereket eredményez.

Ezért a következő kóddal szokás kiegészíteni:

import java.security.*;
import java.io.*;
import java.util.Arrays; // Ez opcionális
class md52
{
        public static void main(String args[]) throws IOException, NoSuchAlgorithmException
        {
                System.out.println("Titkosítás egyirányba");
 
                // Lehetséges algoritmusok: SHA, MD5
                MessageDigest md = MessageDigest.getInstance("NIST");
                byte[] sb = md.digest("titkos".getBytes());
 
                System.out.println(new String(sb));
		System.out.println(Arrays.toString(sb));  //Tömbként íratjuk ki (opcionális)
 
 
		//átalakítjuk megjeleníthető karakterekké:
                StringBuffer hexSzoveg = new StringBuffer();
                for (int i=0; i<sb.length; i++) 
		{
                        String hex = Integer.toHexString(0xFF & sb[i]);  // A hexben általában 2 karaker van
			if(hex.length() == 1) hexSzoveg.append('0');   // Ha mégsem, akkor hozzáfűzünk egy 0-át.
                        hexSzoveg.append(hex);
                }
 
		System.out.println(hexSzoveg);
 
                System.in.read();
        }
}

Az SHA-512 algoritmust szoktuk használni. De mit jelent a 512. Az 512, 512 bitet jelent. Azaz 64 byte. Egy byte-t 2 hexadecimális karakterrel ábrázolunk, az egy SHA-512-es algoritmussal kódolt jelszó 128 darab karaktert fog tartalmazni.

A „titok” szó SHA-512 algoritmussal kódolt kivonata:

f5596f6fef51169defe7cc7bba87576562d91e2ffb34d235e9ad9e13319c6f0e080c0d69a85135ae60f6bd42967159a5111a8ed65393df3cc7e2afa4301d939f

Az „alma” szó SHA-512 algoritmussal kódolt kivonata:

83b05d98186648cd5576ed158c9cf2174413b86d48720c3ffbe6452bc38a6527256ff3435eb1698f24efbc880c8ea870afe314f3004c71cfdd5f0e3c00e3979f

Az SHA1 160 bites kódolás, 40 karaktert eredményez.

A „titok” szó SHA1 kivonata:

46ff53e764c4acf97b54db2020573049d2e3dab3

Az „alma” szó SHA1 kivonata:

5f5ea3800d9a62bc5a008759dbbece9cad5db58f

Minta

Makefile
MAINCLASS=Program01
SOURCES=Program01.java
 
all:
	javac $(SOURCES)
 
 
LINJUNIT=/usr/share/java/junit4.jar
TESTSOURCE=Program01Test
 
testl:
	javac -cp .:$(LINJUNIT) $(TESTSOURCE).java
	java -cp .:$(LINJUNIT) org.junit.runner.JUnitCore $(TESTSOURCE)
 
 
WINJUNIT=c:\bin\SWScite\SWScite_0.5.2_20140505\javalibs\junit-4.11.jar
WINHAMCREST=c:\bin\SWScite\SWScite_0.5.2_20140505\javalibs\hamcrest-core-1.3.jar
 
testw:
	javac -cp .;$(WINJUNIT);$(WINHAMCREST) $(TESTSOURCE).java
	java -cp .;$(WINJUNIT);$(WINHAMCREST) org.junit.runner.JUnitCore $(TESTSOURCE)
 
jar:
	echo "Main-Class: $(MAINCLASS)" > manifest.mf
	jar cvfm $(MAINCLASS).jar manifest.mf *.class
	echo "#!/bin/bash" > startProgram.sh
	echo "java -jar $(MAINCLASS).jar" >> startProgram.sh
	echo "java -jar $(MAINCLASS).JAR" > startProgram.bat
Program01Test.java
import org.junit.Test;
import static org.junit.Assert.*;
 
public class Program01Test {
	@Test
	public void testDigest() {
		String d1 = "46ff53e764c4acf97b54db2020573049d2e3dab3";		
		assertEquals(d1, Program01.digest("titok"));
 
		String d2 = "5f5ea3800d9a62bc5a008759dbbece9cad5db58f";
		assertEquals(d2, Program01.digest("alma"));
	}
}
Program01.java
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
 
class Program01 {
	public static String digest(String clearText) {
		String digestText = null;
		try {
			digestText = tryDigest(clearText);
		}catch(NoSuchAlgorithmException ex) {
			System.err.println("Nincs ilyen algoritmus");
		}
		return digestText;
	}
	public static String tryDigest(String clearText) 
		throws NoSuchAlgorithmException {
 
		MessageDigest md = MessageDigest.getInstance("SHA1");
		byte[] sb = md.digest(clearText.getBytes());
 
		StringBuffer hexText = new StringBuffer();
		for (int i=0; i<sb.length; i++) {
			String hex = Integer.toHexString(0xFF & sb[i]);
			if(hex.length() == 1) {
				hexText.append('0');
			}
			hexText.append(hex);
		}		
		return hexText.toString();
	}
	public static void main(String[] args) {		
		System.out.println(digest("titok"));
	}
}

Linkek