本文介紹了java.security.NoSuchAlgorithmException:RSA 簽名不可用的處理方法,對(duì)大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
這是個(gè)例外
<上一頁>線程主"java.security.NoSuchAlgorithmException 中的異常:RSA 簽名不可用在 java.security.Signature.getInstance(Signature.java:229)在 MailClient.main(MailClient.java:52)這是我的代碼
import java.io.*;導(dǎo)入java.net.*;導(dǎo)入 java.nio.ByteBuffer;導(dǎo)入 java.util.*;導(dǎo)入java.security.*;公共類 MailClient {公共字符串 getMessage(郵件 m){返回 m.message;}公共靜態(tài) void main(String[] args) 拋出異常 {//初始化BufferedReader br = new BufferedReader(new InputStreamReader(System.in));字符串主機(jī) = args[0];int 端口 = Integer.parseInt(args[1]);字符串用戶 ID = args[2];而(真){//連接到服務(wù)器套接字 s = 新套接字(主機(jī),端口);DataInputStream dis = new DataInputStream(s.getInputStream());DataOutputStream dos = new DataOutputStream(s.getOutputStream());ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());oos.flush();ObjectInputStream ois = new ObjectInputStream(s.getInputStream());//待辦事項(xiàng):登錄//這兩行只是為了讓提供的程序運(yùn)行而不會(huì)崩潰.//你可能想改變它們,當(dāng)然在它們之后添加?xùn)|西dos.writeUTF(userid);字符串 userPrivateKeyFileName = 用戶 ID + ".prv";//獲取創(chuàng)建簽名的密鑰ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(userPrivateKeyFileName));PrivateKey privateKey = (PrivateKey)keyIn.readObject();keyIn.close();//創(chuàng)建時(shí)間戳和隨機(jī)數(shù)long t1 = (new Date()).getTime();雙 q1 = Math.random();//ByteBuffer 稍后轉(zhuǎn)換為字節(jié)ByteBuffer bb = ByteBuffer.allocate(16);bb.putLong(t1);bb.putDouble(q1);//創(chuàng)建簽名,使用時(shí)間戳和隨機(jī)數(shù)作為數(shù)據(jù)簽名 sig = Signature.getInstance("RSA");sig.initSign(privateKey);sig.update(bb.array());字節(jié)[] 簽名 = sig.sign();//發(fā)送數(shù)據(jù)和簽名DataOutputStream out = new DataOutputStream(s.getOutputStream());out.writeUTF(userid);out.writeLong(t1);out.writeDouble(q1);out.writeInt(signature.length);out.write(簽名);out.flush();布爾答案 = dis.readBoolean();//通過了驗(yàn)證登錄如果(回答){//接收多少條消息int numMsg = dis.readInt();System.out.println("你有 " + numMsg + " 收到的消息.");//TO DO:閱讀消息ArrayList<郵件>msg = new ArrayList<>(numMsg);for(int i=0;i) ois.readObject();}而(!msg.isEmpty()){//對(duì)于每封郵件,顯示發(fā)件人、時(shí)間戳、消息System.out.println(msg.get(0).sender);System.out.println(msg.get(0).timestamp);System.out.println(msg.get(0).message);MessageDigest md = MessageDigest.getInstance("SHA-1");md.update(msg.get(0).hashcash);字節(jié)[] 摘要 = md.digest();boolean normalMail = msg.get(0).checkHashcash(digest);如果(正常郵件){//檢查每封郵件是否為原始郵件未被修改//接收郵件System.out.println(msg.get(0).message);}else{System.out.println("這是垃圾郵件");System.out.println(msg.get(0).message);}msg.remove(0);}//發(fā)送信息System.out.println("您要發(fā)送消息[Y/N]?");String wantToSend = br.readLine();如果(!wantToSend.equals(Y")){dos.writeBoolean(false);返回 ;}dos.writeBoolean(true);System.out.println("請(qǐng)輸入收件人的用戶名:");字符串接收者 = br.readLine();System.out.println("請(qǐng)輸入您的信息:");字符串消息 = br.readLine();//TO DO:發(fā)送郵件郵件 m = 新郵件(用戶 ID、收件人、郵件);MessageDigest md = MessageDigest.getInstance("SHA-1");md.update(m.hashcash);字節(jié)[] 摘要 = md.digest();而(m.checkHashcash(摘要)){m.setHashcash(摘要);}out.write(摘要);out.flush();//發(fā)送時(shí)間戳和摘要到服務(wù)器長(zhǎng)郵件時(shí)間戳 = m.timestamp.getTime();out.writeLong(mailTimestamp);oos.writeObject(m);}}}}
解決方案
如果你運(yùn)行下面的代碼,你會(huì)得到一個(gè)你的Java安裝支持的簽名算法列表.
TreeSet算法=新樹集<>();對(duì)于(提供者提供者:Security.getProviders())對(duì)于(服務(wù)服務(wù):provider.getServices())if (service.getType().equals("簽名"))算法.add(service.getAlgorithm());對(duì)于(字符串算法:算法)System.out.println(算法);
當(dāng)我運(yùn)行它(Windows,Java 1.8.0_65)時(shí),我得到:
MD2withRSAMD5 和 SHA1 和 RSA帶有 RSA 的 MD5NONEwithDSANONEwithECDSANONEwithRSA帶有 DSA 的 SHA1SHA1 和 ECDSASHA1withRSASHA224 和 DSASHA224 和 ECDSASHA224 和 RSA帶有 DSA 的 SHA256SHA256 和 ECDSASHA256 和 RSASHA3??84 和 ECDSASHA3??84 和 RSASHA512 和 ECDSASHA512 和 RSA
如您所見,RSA
不是有效的簽名算法.
也許 NONEwithRSA
是你所追求的?
this is exception
Exception in thread "main" java.security.NoSuchAlgorithmException: RSA Signature not available at java.security.Signature.getInstance(Signature.java:229) at MailClient.main(MailClient.java:52)
this is my code
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.util.*;
import java.security.*;
public class MailClient {
public String getMessage(Mail m){
return m.message;
}
public static void main(String[] args) throws Exception {
// Initialisation
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String host = args[0];
int port = Integer.parseInt(args[1]);
String userid = args[2];
while(true) {
// connect to server
Socket s = new Socket(host,port);
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
oos.flush();
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
// TO DO: login
// these two lines are here just to make the supplied programs run without crashing.
// You may want to change them, and certainly add things after them
dos.writeUTF(userid);
String userPrivateKeyFileName = userid + ".prv";
// Get the key to create the signature
ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(userPrivateKeyFileName));
PrivateKey privateKey = (PrivateKey)keyIn.readObject();
keyIn.close();
// create timeStamp and random number
long t1 = (new Date()).getTime();
double q1 = Math.random();
// ByteBuffer to convert to bytes later
ByteBuffer bb = ByteBuffer.allocate(16);
bb.putLong(t1);
bb.putDouble(q1);
// create signature, using timeStamp and random number as data
Signature sig = Signature.getInstance("RSA");
sig.initSign(privateKey);
sig.update(bb.array());
byte[] signature = sig.sign();
// send data and signature
DataOutputStream out = new DataOutputStream(s.getOutputStream());
out.writeUTF(userid);
out.writeLong(t1);
out.writeDouble(q1);
out.writeInt(signature.length);
out.write(signature);
out.flush();
boolean answer = dis.readBoolean();
//passed the verifyLogin
if (answer)
{
// receive how many messages
int numMsg = dis.readInt();
System.out.println("You have " + numMsg + " incoming messages.");
// TO DO: read messages
ArrayList<Mail> msg = new ArrayList<>(numMsg);
for(int i=0;i<numMsg;i++){
//@Unchecked
msg = (ArrayList<Mail>) ois.readObject();
}
while(!msg.isEmpty()){
//for each mail, display sender,timestamp,message
System.out.println(msg.get(0).sender);
System.out.println(msg.get(0).timestamp);
System.out.println(msg.get(0).message);
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(msg.get(0).hashcash);
byte[] digest = md.digest();
boolean normalMail = msg.get(0).checkHashcash(digest);
if(normalMail){
//check each mail is original that it isn't modified
//receive mail
System.out.println(msg.get(0).message);
}
else{System.out.println("it's a spam message.");
System.out.println(msg.get(0).message);
}
msg.remove(0);
}
// send messages
System.out.println("Do you want to send a message [Y/N]?");
String wantToSend = br.readLine();
if (!wantToSend.equals("Y")) {
dos.writeBoolean(false);
return ;
}
dos.writeBoolean(true);
System.out.println("Enter userid of recipient:");
String recipient = br.readLine();
System.out.println("Type your message:");
String message = br.readLine();
// TO DO: send mail
Mail m = new Mail(userid, recipient, message);
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(m.hashcash);
byte[] digest = md.digest();
while(m.checkHashcash(digest)){
m.setHashcash(digest);
}
out.write(digest);
out.flush();
// send timeStamp and digest to server
long mailTimestamp = m.timestamp.getTime();
out.writeLong(mailTimestamp);
oos.writeObject(m);
}
}
}
}
解決方案
If you run the following code, you will get a list of signature algorithms supported by your Java installation.
TreeSet<String> algorithms = new TreeSet<>();
for (Provider provider : Security.getProviders())
for (Service service : provider.getServices())
if (service.getType().equals("Signature"))
algorithms.add(service.getAlgorithm());
for (String algorithm : algorithms)
System.out.println(algorithm);
When I run it (Windows, Java 1.8.0_65), I get:
MD2withRSA
MD5andSHA1withRSA
MD5withRSA
NONEwithDSA
NONEwithECDSA
NONEwithRSA
SHA1withDSA
SHA1withECDSA
SHA1withRSA
SHA224withDSA
SHA224withECDSA
SHA224withRSA
SHA256withDSA
SHA256withECDSA
SHA256withRSA
SHA384withECDSA
SHA384withRSA
SHA512withECDSA
SHA512withRSA
As you can see, RSA
is not a valid signature algorithm.
Maybe NONEwithRSA
is what you're after?
這篇關(guān)于java.security.NoSuchAlgorithmException:RSA 簽名不可用的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!
【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請(qǐng)聯(lián)系我們刪除處理,感謝您的支持!