本代码采用的是AES加密算法实现一个密钥生成器。
项目结构如下所示:
【代码如下】
LicenseEntry.java
package cn.evansung.license;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.DateFormatter;
public class LicenseEntry {
public static void main(String[] args) {
LicenseFrame frame = new LicenseFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class LicenseFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final int WIDTH = 475;
private static final int HEIGHT = 445;
private JTextField userNameInput;
private JFormattedTextField dueTimeInput;
private JTextField socketInput;
private JTextField brandInput;
private JTextField productInput;
private JTextArea keyOutput;
public LicenseFrame() {
Container con = getContentPane();
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int width = screenSize.width;
int height = screenSize.height;
int x = (width - WIDTH) / 2;
int y = (height - HEIGHT) / 2;
setLocation(x, y);
setSize(WIDTH, HEIGHT);
setResizable(false);
//设置图标
Image image = kit.getImage("image/favicon.png");
setIconImage(image);
setTitle("License builder - Undefined");
setFont(new Font("Dialog", 0, 12));
JLabel label1 = new JLabel("Username:");
label1.setBounds(65, 45, 80, 30);
userNameInput = new JTextField();
userNameInput.setBounds(140, 45, 180, 30);
JLabel label2 = new JLabel("DueTime:");
label2.setBounds(65, 90, 80, 30);
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
DateFormatter df = new DateFormatter(format);
dueTimeInput = new JFormattedTextField(df);
dueTimeInput.setValue(new Date());
dueTimeInput.setBounds(140, 90, 180, 30);
JLabel label3 = new JLabel("Socket:");
label3.setBounds(65, 135, 80, 30);
socketInput = new JTextField();
socketInput.setBounds(140, 135, 180, 30);
JLabel label4 = new JLabel("Brand:");
label4.setBounds(65, 180, 80, 30);
brandInput = new JTextField();
brandInput.setBounds(140, 180, 180, 30);
JLabel label5 = new JLabel("Product:");
label5.setBounds(65, 225, 80, 30);
productInput = new JTextField();
productInput.setBounds(140, 225, 180, 30);
JLabel label6 = new JLabel("Key:");
label6.setBounds(65, 270, 80, 30);
keyOutput = new JTextArea(5, 20);
keyOutput.setLineWrap(true);
keyOutput.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.black));
keyOutput.setBounds(140, 270, 300, 70);
JPanel contentPanel = new JPanel();
contentPanel.setLayout(null);
contentPanel.add(label1);
contentPanel.add(label2);
contentPanel.add(label3);
contentPanel.add(label4);
contentPanel.add(label5);
contentPanel.add(label6);
contentPanel.add(userNameInput);
contentPanel.add(dueTimeInput);
contentPanel.add(socketInput);
contentPanel.add(brandInput);
contentPanel.add(productInput);
contentPanel.add(keyOutput);
con.add(contentPanel);
ButtonPanel southPanel = new ButtonPanel(contentPanel);
con.add(southPanel, BorderLayout.SOUTH);
}
private class ButtonPanel extends JPanel {
private static final long serialVersionUID = 1L;
private JPanel centerPanel;
private JButton create;
private JButton check;
public ButtonPanel(JPanel centerPanel) {
this.centerPanel = centerPanel;
create = new JButton("Create");
check = new JButton("Check");
ButtonGroup group = new ButtonGroup();
group.add(create);
group.add(check);
add(create);
add(check);
create.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
createBtnActionPerformed(event);
}
});
check.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
checkBtnActionPerformed(event);
}
});
}
private void createBtnActionPerformed(ActionEvent event) {
Date date = null;
try {
date = (Date) dueTimeInput.getValue();
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "时间格式错误:" + dueTimeInput.getValue(), "错误提示", 0);
return;
}
long timestamp = date.getTime();
//86300000L为一天的毫秒数
if (timestamp - System.currentTimeMillis() > 86300000L) {
String username = userNameInput.getText().trim();
if ((username == null) || (username.isEmpty())) {
JOptionPane.showMessageDialog(null, "用户不能为空", "消息提示", 1);
return;
}
try {
String socket_text = socketInput.getText();
long socket = 1L;
if (isNumeric(socket_text)) {
socket = Long.valueOf(socket_text).longValue();
}
long day = (timestamp / 1000L - 1493568000L) / 3600L / 24L;
String storekey = day + ":" + socket + ":" + brandInput.getText().trim() + ":" + productInput.getText().trim();
String key = AESCore.encrypt(storekey.getBytes(), "fiwouser-" + username);
keyOutput.setText(key);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "生成失败:" + e.getMessage(), "错误提示", 0);
}
} else {
JOptionPane.showMessageDialog(null, "有效时间至少超过1天,请修改duetime", "消息提示", 1);
return;
}
centerPanel.setBackground(Color.CYAN);
}
private void checkBtnActionPerformed(ActionEvent event) {
String key = keyOutput.getText();
String name = userNameInput.getText();
if ((key.isEmpty()) || (name.isEmpty())) {
centerPanel.setBackground(null);
JOptionPane.showMessageDialog(null, "请检查key或name是否为空", "消息提示", 1);
return;
}
try {
String keystore = AESCore.decrypt(key, "user-" + name);
String[] keys = keystore.split(":");
if ((keys.length >= 1) && (isNumeric(keys[0]))) {
//设置时间基准2017/05/01(1493568000000L)
long time = 1493568000000L + Long.valueOf(keys[0]).longValue() * 24L * 3600L * 1000L;
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(time);
dueTimeInput.setValue(cal.getTime());
if (time < System.currentTimeMillis()) {
centerPanel.setBackground(null);
JOptionPane.showMessageDialog(null, "该key已过期", "消息提示", 1);
return;
}
centerPanel.setBackground(Color.CYAN);
JOptionPane.showMessageDialog(null, "该key有效", "消息提示", 1);
return;
}
centerPanel.setBackground(null);
JOptionPane.showMessageDialog(null, "无效key", "消息提示", 1);
} catch (Exception e) {
centerPanel.setBackground(null);
JOptionPane.showMessageDialog(null, "验证失败:" + e.getMessage(), "错误提示", 0);
}
}
private boolean isNumeric(Object s) {
return ((s == null) ? false : s.toString().matches(
"^[-+]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?[dD]?$"));
}
}
}
AESCore.java
package cn.evansung.license;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
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 AESCore {
public static String encrypt(String bef_aes, String password) {
byte[] byteContent = null;
try {
byteContent = bef_aes.getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return encrypt(byteContent, password);
}
public static String encrypt(byte[] content, String password) {
SecretKey secretKey;
try {
secretKey = getKey(password);
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(1, key);
byte[] result = cipher.doFinal(content);
String aft_aes = parseByte2HexStr(result);
return aft_aes;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
public static String decrypt(String aft_aes, String password) {
byte[] content;
try {
content = parseHexStr2Byte(aft_aes);
SecretKey secretKey = getKey(password);
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(2, key);
byte[] result = cipher.doFinal(content);
String bef_aes = new String(result);
return bef_aes;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
public static String parseByte2HexStr(byte[] buf) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; ++i) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1)
hex = '0' + hex;
sb.append(hex.toUpperCase());
}
return sb.toString();
}
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; ++i) {
int value = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2), 16);
result[i] = (byte)value;
}
return result;
}
public static SecretKey getKey(String strKey) {
KeyGenerator _generator;
try {
_generator = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(strKey.getBytes());
_generator.init(128, secureRandom);
return _generator.generateKey();
} catch (Exception e) {
throw new RuntimeException("初始化密钥出现异常");
}
}
}
【运行后的 结果】