考虑:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.io.*;
public class EncryptURL extends JApplet implements ActionListener {
Container content;
JTextField userName = new JTextField();
JTextField firstName = new JTextField();
JTextField lastName = new JTextField();
JTextField email = new JTextField();
JTextField phone = new JTextField();
JTextField heartbeatID = new JTextField();
JTextField regionCode = new JTextField();
JTextField retRegionCode = new JTextField();
JTextField encryptedTextField = new JTextField();
JPanel finishPanel = new JPanel();
public void init() {
//setTitle("Book - E Project");
setSize(800, 600);
content = getContentPane();
content.setBackground(Color.yellow);
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
JButton submit = new JButton("Submit");
content.add(new JLabel("User Name"));
content.add(userName);
content.add(new JLabel("First Name"));
content.add(firstName);
content.add(new JLabel("Last Name"));
content.add(lastName);
content.add(new JLabel("Email"));
content.add(email);
content.add(new JLabel("Phone"));
content.add(phone);
content.add(new JLabel("HeartBeatID"));
content.add(heartbeatID);
content.add(new JLabel("Region Code"));
content.add(regionCode);
content.add(new JLabel("RetRegionCode"));
content.add(retRegionCode);
content.add(submit);
submit.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "Submit"){
String subUserName = userName.getText();
String subFName = firstName.getText();
String subLName = lastName.getText();
String subEmail = email.getText();
String subPhone = phone.getText();
String subHeartbeatID = heartbeatID.getText();
String subRegionCode = regionCode.getText();
String subRetRegionCode = retRegionCode.getText();
String concatURL =
"user=" + subUserName + "&f=" + subFName +
"&l=" + subLName + "&em=" + subEmail +
"&p=" + subPhone + "&h=" + subHeartbeatID +
"&re=" + subRegionCode + "&ret=" + subRetRegionCode;
concatURL = padString(concatURL, ' ', 16);
byte[] encrypted = encrypt(concatURL);
String encryptedString = bytesToHex(encrypted);
content.removeAll();
content.add(new JLabel("Concatenated User Input -->" + concatURL));
content.add(encryptedTextField);
setContentPane(content);
}
}
public static byte[] encrypt(String toEncrypt) throws Exception{
try{
String plaintext = toEncrypt;
String key = "01234567890abcde";
String iv = "fedcba9876543210";
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
}
catch(Exception e){
}
}
public static byte[] decrypt(byte[] toDecrypt) throws Exception{
String key = "01234567890abcde";
String iv = "fedcba9876543210";
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] decrypted = cipher.doFinal(toDecrypt);
return decrypted;
}
public static String bytesToHex(byte[] data) {
if (data == null)
{
return null;
}
else
{
int len = data.length;
String str = "";
for (int i=0; i<len; i++)
{
if ((data[i]&0xFF) < 16)
str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
else
str = str + java.lang.Integer.toHexString(data[i]&0xFF);
}
return str;
}
}
public static String padString(String source, char paddingChar, int size)
{
int padLength = size-source.length() % size;
for (int i = 0; i < padLength; i++) {
source += paddingChar;
}
return source;
}
}
Run Code Online (Sandbox Code Playgroud)
我得到一个未报告的例外:
java.lang.Exception; must be caught or declared to be thrown
byte[] encrypted = encrypt(concatURL);
Run Code Online (Sandbox Code Playgroud)
以及:
.java:109: missing return statement
Run Code Online (Sandbox Code Playgroud)
我该如何解决这些问题?
vic*_*ugo 33
你所有的问题都源于此
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
Run Code Online (Sandbox Code Playgroud)
其中包含在try,catch块中,问题是如果程序发现异常,则不返回任何内容.像这样(将其修改为程序逻辑):
public static byte[] encrypt(String toEncrypt) throws Exception{
try{
String plaintext = toEncrypt;
String key = "01234567890abcde";
String iv = "fedcba9876543210";
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE,keyspec,ivspec);
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
} catch(Exception e){
return null; // Always must return something
}
}
Run Code Online (Sandbox Code Playgroud)
对于第二个,您必须从加密方法调用中捕获异常,如下所示(也可以将其修改为程序逻辑):
public void actionPerformed(ActionEvent e)
.
.
.
try {
byte[] encrypted = encrypt(concatURL);
String encryptedString = bytesToHex(encrypted);
content.removeAll();
content.add(new JLabel("Concatenated User Input -->" + concatURL));
content.add(encryptedTextField);
setContentPane(content);
} catch (Exception exc) {
// TODO: handle exception
}
}
Run Code Online (Sandbox Code Playgroud)
你必须从中吸取教训:
问题出在这个方法中:
public static byte[] encrypt(String toEncrypt) throws Exception{
Run Code Online (Sandbox Code Playgroud)
这是方法签名,几乎说:
在这种情况下,方法签名表示在调用时,此方法"可能"可能会抛出"异常"类型的异常.
....
concatURL = padString(concatURL, ' ', 16);
byte[] encrypted = encrypt(concatURL); <-- HERE!!!!!
String encryptedString = bytesToHex(encrypted);
content.removeAll();
......
Run Code Online (Sandbox Code Playgroud)
因此编译器会说:要么用try/catch构造包围它,要么声明方法(正在使用的地方)自己抛出"Exception".
真正的问题是"加密"方法定义.没有方法应该返回"Exception",因为它太通用了,可能隐藏其他类型的异常更好的是有一个特定的异常.
试试这个:
public static byte[] encrypt(String toEncrypt) {
try{
String plaintext = toEncrypt;
String key = "01234567890abcde";
String iv = "fedcba9876543210";
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE,keyspec,ivspec);
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
} catch ( NoSuchAlgorithmException nsae ) {
// What can you do if the algorithm doesn't exists??
// this usually won't happen because you would test
// your code before shipping.
// So in this case is ok to transform to another kind
throw new IllegalStateException( nsae );
} catch ( NoSuchPaddingException nspe ) {
// What can you do when there is no such padding ( whatever that means ) ??
// I guess not much, in either case you won't be able to encrypt the given string
throw new IllegalStateException( nsae );
}
// line 109 won't say it needs a return anymore.
}
Run Code Online (Sandbox Code Playgroud)
基本上在这种特殊情况下,您应该确保加密包在系统中可用.
Java需要加密包的扩展,因此,异常被声明为"已检查"的异常.当你不在场时你可以处理.
在这个小程序中,如果加密包不可用,则无法执行任何操作,因此请在"开发"时检查该程序.如果在程序运行时抛出这些异常是因为你在"开发"中做错了,那么RuntimeException子类更合适.
最后一行不再需要return语句,在第一个版本中你捕获异常并且什么都不做,这是错误的.
try {
// risky code ...
} catch( Exception e ) {
// a bomb has just exploited
// you should NOT ignore it
}
// The code continues here, but what should it do???
Run Code Online (Sandbox Code Playgroud)
如果代码失败,最好快速失败
以下是一些相关的答案:
第一个错误
java.lang.Exception的; 必须被捕获或声明被抛出byte [] encrypted = encrypt(concatURL);
表示您的encrypt方法抛出一个异常,该异常未被actionPerformed您调用它的方法处理或声明.阅读Java Exceptions Tutorial中的所有相关内容.
您可以选择几个选项来获取要编译的代码.
throws Exception从encrypt方法中删除并实际处理内部异常encrypt.encrypt并将throws Exception异常处理块添加到您的actionPerformed方法中.通常最好在最低级别处理异常,而不是将其传递到更高级别.
第二个错误只是意味着您需要将return语句添加到包含第109行的任何方法(encrypt在本例中也是如此).方法中有一个return语句,但如果抛出异常,则可能无法访问它,因此您需要返回catch块,或者删除try/catch encrypt,如前所述.