【问题标题】:Java encryption using AES使用 AES 的 Java 加密
【发布时间】:2016-10-19 00:44:43
【问题描述】:

我正在尝试使用 AES 类制作加密系统:

package Source;
import java.security.MessageDigest;
import java.util.Arrays;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;

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

public class AES {
  static String IV = "AAAAAAAAAAAAAAAA";
  static String plaintext = "test text 123\0\0\0"; /*Note null padding*/
  static String encryptionKey = "H4tch4repratygonetowil5h4kers";
  public static void main(String [] args) {
    try {

      System.out.println("==Java==");
      System.out.println("plain:   " + plaintext);

      byte[] cipher = encrypt(plaintext, encryptionKey);

      System.out.print("cipher:  ");
      for (int i=0; i<cipher.length; i++)
        System.out.print(new Integer(cipher[i])+" ");
      System.out.println("");

      String decrypted = decrypt(cipher, encryptionKey);

      System.out.println("decrypt: " + decrypted);

    } catch (Exception e) {
      e.printStackTrace();
    } 
  }

  public static byte[] encrypt(String plainText, String encryptionKey) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
    SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
    cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
    return cipher.doFinal(plainText.getBytes("UTF-8"));
  }

  private static String decrypt(byte[] cipherText, String encryptionKey) throws Exception{
    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
    SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
    cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
    return new String(cipher.doFinal(cipherText),"UTF-8");
  }
}

这是我的代码实现:

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextPane;


import Source.AES;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import javax.swing.JTextArea;

public class first {

    private JFrame frame;
    private JPasswordField passwordField;
    private JTextArea txtrEnterTextHere;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    first window = new first();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public first() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JOptionPane.showMessageDialog(null, "Welcome to Encryption System! ");
        JButton btnNewButton = new JButton("Send Info");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                String text = txtrEnterTextHere.getText();
                String pass = passwordField.getText();
                String str = null;
                try {
                    str = new String(AES.encrypt(text, pass));
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                txtrEnterTextHere.setText(str);

                JOptionPane.showMessageDialog(null, "Your intel has been encrypted!");

            }
        });
        frame.getContentPane().add(btnNewButton, BorderLayout.NORTH);

        passwordField = new JPasswordField();
        frame.getContentPane().add(passwordField, BorderLayout.SOUTH);

        txtrEnterTextHere = new JTextArea();
        txtrEnterTextHere.setText("ENTER TEXT HERE AND PASSWORD BELLOW!");

        frame.getContentPane().add(txtrEnterTextHere, BorderLayout.CENTER);
    }

}

如何使变量“str”实际上具有我的加密文本的值?在运行时我收到错误和一个空字段...可以从 byte[] 更改为 string 吗?

更新错误:

java.lang.IllegalArgumentException: 空键 在 javax.crypto.spec.SecretKeySpec.(SecretKeySpec.java:96) 在 Source.AES.encrypt(AES.java:41) 起初$2.actionPerformed(first.java:62) 在 javax.swing.AbstractButton.fireActionPerformed(未知来源) 在 javax.swing.AbstractButton$Handler.actionPerformed(未知来源) 在 javax.swing.DefaultButtonModel.fireActionPerformed(未知来源) 在 javax.swing.DefaultButtonModel.setPressed(未知来源) 在 javax.swing.plaf.basic.BasicButtonListener.mouseReleased(未知来源) 在 java.awt.Component.processMouseEvent(未知来源) 在 javax.swing.JComponent.processMouseEvent(未知来源) 在 java.awt.Component.processEvent(未知来源) 在 java.awt.Container.processEvent(未知来源) 在 java.awt.Component.dispatchEventImpl(未知来源) 在 java.awt.Container.dispatchEventImpl(未知来源) 在 java.awt.Component.dispatchEvent(未知来源) 在 java.awt.LightweightDispatcher.retargetMouseEvent(未知来源) 在 java.awt.LightweightDispatcher.processMouseEvent(未知来源) 在 java.awt.LightweightDispatcher.dispatchEvent(未知来源) 在 java.awt.Container.dispatchEventImpl(未知来源) 在 java.awt.Window.dispatchEventImpl(未知来源) 在 java.awt.Component.dispatchEvent(未知来源) 在 java.awt.EventQueue.dispatchEventImpl(未知来源) 在 java.awt.EventQueue.access$500(未知来源) 在 java.awt.EventQueue$3.run(未知来源) 在 java.awt.EventQueue$3.run(未知来源) 在 java.security.AccessController.doPrivileged(本机方法) 在 java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(未知来源) 在 java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(未知来源) 在 java.awt.EventQueue$4.run(未知来源) 在 java.awt.EventQueue$4.run(未知来源) 在 java.security.AccessController.doPrivileged(本机方法) 在 java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(未知来源) 在 java.awt.EventQueue.dispatchEvent(未知来源) 在 java.awt.EventDispatchThread.pumpOneEventForFilters(未知来源) 在 java.awt.EventDispatchThread.pumpEventsForFilter(未知来源) 在 java.awt.EventDispatchThread.pumpEventsForHierarchy(未知来源) 在 java.awt.EventDispatchThread.pumpEvents(未知来源) 在 java.awt.EventDispatchThread.pumpEvents(未知来源) 在 java.awt.EventDispatchThread.run(未知来源)

【问题讨论】:

  • 你得到的运行时错误是什么?
  • 我已经更新了我的帖子
  • 从错误来看,SecretKeySpec构造函数似乎有问题
  • 一般建议:请不要使用固定的 IV。 IV 是一个非秘密值,当它在加密期间新生成时应该提供语义安全性。由于它不是秘密的,它可以与密文一起发送。一种常见的方法是在加密期间将其添加到密文中,并在解密期间将其切掉。

标签: java encryption


【解决方案1】:

这里有几个问题。

  1. 您有Empty key at javax.crypto.spec.SecretKeySpec 异常,因为您没有输入任何密码。

  2. 输入密码后,您将遇到 Invalid AES key length: 8 bytes 之类的异常,因为密钥应具有特定长度(请参阅 here 的更多信息)。

  3. 使用哈希生成密钥后,您将遇到以下异常 - javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes,因为您的加密模式不使用填充。您可以将其更改为 AES/CBC/PKCS5Padding

最后用下面的“加密”方法你会得到你想要的:

public static byte[] encrypt(String plainText, String encryptionKey) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE");
    MessageDigest sha = MessageDigest.getInstance("SHA-1");
    byte [] hashedPassword = sha.digest(encryptionKey.getBytes("UTF-8"));
    hashedPassword = Arrays.copyOf(hashedPassword, 16);
    SecretKeySpec key = new SecretKeySpec(hashedPassword, "AES");
    cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
    return cipher.doFinal(plainText.getBytes("UTF-8"));
}

(*) 当然,为了解密消息,您还必须在“解密”方法中进行类似的更改...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-24
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 2016-08-21
    • 2013-07-24
    相关资源
    最近更新 更多