简体   繁体   English

Java逐字加密

[英]Java encrypt word by word

I'm trying to take in a long string and encrypt it using the following code: 我试图输入一个长字符串并使用以下代码对其进行加密:

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

public class AESEncrypt {

    /**
     * Turns array of bytes into string
     * 
     * @param buf
     *            Array of bytes to convert to hex string
     * @return Generated hex string
     */
    public static String asHex(byte buf[]) {
        StringBuffer strbuf = new StringBuffer(buf.length * 2);
        int i;

        for (i = 0; i < buf.length; i++) {
            if (((int) buf[i] & 0xff) < 0x10)
                strbuf.append("0");

            strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
        }

        return strbuf.toString();
    }

    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character
                    .digit(s.charAt(i + 1), 16));
        }
        return data;
    }

    public static void main(String[] args) throws Exception {

        String message = "Test text!";

        // Get the KeyGenerator
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128); // 192 and 256 bits may not be available

        // Generate the secret key specs.
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();

        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        System.out.println("Key: " + asHex(raw));

        // Instantiate the cipher

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

        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        byte[] encrypted = cipher.doFinal((args.length == 0 ? message : args[0]).getBytes());
        System.out.println("encrypted string: " + asHex(encrypted));

    }
}

However, I would like to encrypt word by word and print out the encrypted text as such: 但是,我想逐字加密并以这种方式打印出加密的文本:

Original string -> Test text! 原始字符串->测试文本!

Encrypted string -> 29f84h2f 23f9f92jf3 加密的字符串-> 29f84h2f 23f9f92jf3

I couldn't find any examples online that could help me out. 我在网上找不到任何可以帮助我的例子。 Is there anyway I can achieve this? 无论如何,我能做到这一点吗?

AES is a block cypher, and it uses 16 byte blocks. AES是一个块密码,它使用16个字节的块。 It does not work in words, but in fixed blocks. 它不能以文字形式工作,而是以固定的块形式工作。 If you want to split up your text into varying size words then you will likely get closer to what you want by using either a stream cypher, such as RC4, or alternatively AES in CTR mode, which effectively turns AES into a stream cypher. 如果要将文本分成大小不同的单词,则可以通过使用流密码(例如RC4)或以CTR模式使用AES(更有效地将AES转换为流密码)来更接近所需内容。 Stream cyphers do not work in blocks, but in bytes. 流密码不是以块为单位,而是以字节为单位。 You can take 3 bytes off the stream for a 3 letter word, or nine bytes off the stream for a 9 letter word. 对于3个字母的单词,您可以从流中删除3个字节,对于9个字母的单词,可以从流中删除9个字节。

You will need to work out what to do with spaces, punctuation etc between words. 您将需要弄清楚单词之间的空格,标点符号等。 You will also need to think about how often you re-key the cypher. 您还需要考虑重新加密密码的频率。 Do you want to re-key for every individual word, or do you just re-key at the start of each string? 您要为每个单词重新输入密钥,还是只是在每个字符串的开头重新输入密钥? As with any stream cypher, never ever use the same key twice. 与任何流密码一样,永远不要两次使用相同的密钥。

Try as below example; 请尝试以下示例; Actually, It just need to used StringTokenizer. 实际上,只需要使用StringTokenizer。 Firstly you have to token your target string. 首先,您必须标记您的目标字符串。 After that, encrypt the token string. 之后,加密令牌字符串。

import java.util.StringTokenizer;

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


public class AES {
    public static String asHex(byte[] buf) {
        StringBuffer strbuf = new StringBuffer(buf.length * 2);
        int i;

        for (i = 0; i < buf.length; i++) {
            if (((int)buf[i] & 0xff) < 0x10)
                strbuf.append("0");
            strbuf.append(Long.toString((int)buf[i] & 0xff, 16));
        }

        return strbuf.toString();
    }

    public static void main(String[] args) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128); // 192 and 256 bits may not be available
        // Generate the secret key specs.
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();

        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        String target = "This is just an example";
        StringTokenizer token = new StringTokenizer(target);
        while(token.hasMoreTokens()) {
            String temp = token.nextToken();
            byte[] encrypted = cipher.doFinal((args.length == 0 ?  temp : args[0]).getBytes());
            System.out.println(asHex(encrypted) + " ");
        }
    }
}

Output : 输出:

    d40186eab04d10e299801e7ad9046c06 6a71265c768a3b6e1f1a8f891d621c1d 735e3f54c8ad7242466e3517e8dd1659 5216643345db0f0c12f65c66c5363be3 b823355d5bb31bf092df98e18fa8001c

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM