1

我的代码

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.*;

import org.apache.commons.codec.binary.Base64;

public class FrontierCipher
{
    private static final String ALGO = "AES";
    private static String keyString = "00112233445566778899AABBCCDDEEFF0123456789ABCDEF0123456789ABCDEF";

     private static Key generateKey() throws Exception 
     {
        Key key = new SecretKeySpec(convertToByteArray(keyString), ALGO);
        return key;
    }
    public static byte[] encryptBytes(byte[] data) throws Exception
    {
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.ENCRYPT_MODE, key);

        byte[] encVal = c.doFinal(data);
        byte[] encryptedValue = Base64.encodeBase64(encVal);

        return encryptedValue;
    }

    public static byte[] decrpytBytes(byte[] encryptedData) throws Exception
    {   
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.DECRYPT_MODE, key);

        byte[] decordedValue = Base64.decodeBase64(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);

        return decValue;
    }

    public static byte[] convertToByteArray(String key) throws KeySizeException
    {
        if(key.length()<64)
            throw new KeySizeException("Key must contain 64 characters");

        byte[] b = new byte[32];

        for(int i=0, bStepper=0; i<key.length()+2; i+=2)
            if(i !=0)
                b[bStepper++]=((byte) Integer.parseInt((key.charAt(i-2)+""+key.charAt(i-1)), 16));

        return b;
    }


    public static void main(String[] args) throws Exception
    {
        byte[] password  = {6,75,3};
        byte[] passwordEnc = encryptBytes(password);
        byte[] passwordDec = decrpytBytes(passwordEnc);

        System.out.println("Plain Text : " + password[0]+" "+ password[1]+" "+ password[2]);
        System.out.println("Encrypted Text : " + passwordEnc[0]+" "+ passwordEnc[1]+" "+ passwordEnc[2]);
        System.out.println("Decrypted Text : " + passwordDec[0]+" "+passwordDec[1]+" "+passwordDec[2]);
    }
}

在本地运行时

Plain Text : 6 75 3
Encrypted Text : 74 43 117
Decrypted Text : 6 75 3

运行时,等待 udp 数据包来我得到这个

   javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
    at javax.crypto.Cipher.doFinal(DashoA13*..)

测试服务器使用

private static void udpServer()
    {
        try
        {      //This is whats coming in ==> byte[] password={6,75,3};

            DatagramSocket serverSocket = new DatagramSocket(18000);
            byte[] receiveData = new byte[64];

            while (true)
            {
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                serverSocket.receive(receivePacket);

                byte[] b = decrpytBytes(receivePacket.getData());
            }
        }
        catch(Exception e)
        {
            //blahh
        }
    }
4

1 回答 1

1

好的,这是一个糟糕的例子,我稍后会更新,我得睡觉了。

请注意,使用 ECB 编码对于普通数据总是不安全的。当可能发生中间人攻击(填充 Oracle 攻击)时,CBC 编码非常不安全。但它应该工作。如果您有更新的 Java 7,请尝试使用"AES/GCM/NoPadding"并且不要忘记将随机 IV 发送到另一端。

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.charset.Charset;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class UDP_AES {


    /**
     * @param args
     * @throws SocketException 
     */
    public static void main(String[] args) throws SocketException {


        Thread t = new Thread(new Runnable() {
            DatagramSocket socket;
            byte[] receiveData = new byte[1024];
            Cipher aesCipher;

            {
                try {
                    socket = new DatagramSocket(18000);
                    aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                    IvParameterSpec zeroIV = new IvParameterSpec(new byte[aesCipher.getBlockSize()]);
                    SecretKey key = new SecretKeySpec(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,}, "AES");
                    aesCipher.init(Cipher.DECRYPT_MODE, key, zeroIV);
                } catch (Exception e) {
                    throw new IllegalStateException("Could not create server socket or cipher", e);
                }

            }

            @Override
            public void run() {
                while (true) {
                    DatagramPacket packet = new DatagramPacket(receiveData, receiveData.length);

                    try {
                        socket.receive(packet);
                        final byte[] plaintextBinary = aesCipher.doFinal(packet.getData(), 0, packet.getLength());
                        String plaintext = new String(plaintextBinary, Charset.forName("UTF-8"));
                        System.out.println(plaintext);
                    } catch (Exception e) {
                        throw new IllegalStateException("Could not receive or decrypt packet");
                    }
                }
            }

        });
        t.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // yeah, whatever
        }

        DatagramSocket sendingSocket = new DatagramSocket();
        String plaintext = "1234";
        byte[] plaintextBinary = plaintext.getBytes(Charset.forName("UTF-8"));

        try {
            Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKey key = new SecretKeySpec(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,}, "AES");
            IvParameterSpec zeroIV = new IvParameterSpec(new byte[aesCipher.getBlockSize()]);
            aesCipher.init(Cipher.ENCRYPT_MODE, key, zeroIV);
            final byte[] ciphertextBinary = aesCipher.doFinal(plaintextBinary);

        DatagramPacket sendingPacket = new DatagramPacket(ciphertextBinary, ciphertextBinary.length);
        sendingPacket.setSocketAddress(new InetSocketAddress("localhost", 18000));
            sendingSocket.send(sendingPacket);
        } catch (Exception e) {
            throw new IllegalStateException("Could not send or encrypt", e);
        }
    }

}
于 2013-02-01T00:10:06.683 回答