考虑:
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我得到一个未报告的例外:
java.lang.Exception; must be caught or declared to be thrown byte[] encrypted = encrypt(concatURL);以及:
.java:109: missing return statement我该如何解决这些问题?
1> victor hugo..:你所有的问题都源于此
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes()); return encrypted;其中包含在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 } }对于第二个,您必须从加密方法调用中捕获异常,如下所示(也可以将其修改为程序逻辑):
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 } }你必须从中吸取教训:
具有返回类型的方法必须始终返回该类型的对象,我的意思是在所有可能的场景中
必须始终处理所有已检查的异常
最后一个要点并不完全正确.RuntimeException是Exception的子类及其子类,是未经检查的异常,不需要被捕获或声明被抛出.
2> OscarRyz..:问题出在这个方法中:
public static byte[] encrypt(String toEncrypt) throws Exception{这是方法签名,几乎说:
方法名称是什么:加密
它接收的参数是什么:名为toEncrypt的String
其访问修饰符:public static
如果它在调用时可能抛出异常.
在这种情况下,方法签名表示在调用时,此方法"可能"可能会抛出"异常"类型的异常.
.... concatURL = padString(concatURL, ' ', 16); byte[] encrypted = encrypt(concatURL); <-- HERE!!!!! String encryptedString = bytesToHex(encrypted); content.removeAll(); ......因此编译器会说:要么用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. }基本上在这种特殊情况下,您应该确保加密包在系统中可用.
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???如果代码失败,最好快速失败
以下是一些相关的答案:
捕获Java中的异常
何时选择已检查和未检查的例外
为什么不必显式声明可能会在Java中抛出一些内置的异常?
除RuntimeException之外的异常
3> Bill the Liz..:第一个错误
java.lang.Exception的; 必须被捕获或声明被抛出byte [] encrypted = encrypt(concatURL);
表示您的
encrypt
方法抛出一个异常,该异常未被actionPerformed
您调用它的方法处理或声明.阅读Java Exceptions Tutorial中的所有相关内容.您可以选择几个选项来获取要编译的代码.
您可以
throws Exception
从encrypt
方法中删除并实际处理内部异常encrypt
.您可以从方法中删除try/catch块
encrypt
并将throws Exception
异常处理块添加到您的actionPerformed
方法中.
通常最好在最低级别处理异常,而不是将其传递到更高级别.
第二个错误只是意味着您需要将return语句添加到包含第109行的任何方法(
encrypt
在本例中也是如此).方法中有一个return语句,但如果抛出异常,则可能无法访问它,因此您需要返回catch块,或者删除try/catchencrypt
,如前所述.