当前位置: 首页 > 知识库问答 >
问题:

JAVA安全NoSuchAlgorithmException:RSA签名不可用

宋育
2023-03-14

这是个例外

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)

这是我的密码

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);

                }
            }


    }

}

共有3个答案

华炜
2023-03-14

指定有效的算法。需要指定哈希算法。例如,SHA256withRSA。

卓正业
2023-03-14

文档

谭修竹
2023-03-14

如果运行以下代码,您将获得Java安装支持的签名算法列表。

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);

当我运行它(Windows,Java 1.8.0\u 65)时,我得到:

MD2withRSA
MD5andSHA1withRSA
MD5withRSA
NONEwithDSA
NONEwithECDSA
NONEwithRSA
SHA1withDSA
SHA1withECDSA
SHA1withRSA
SHA224withDSA
SHA224withECDSA
SHA224withRSA
SHA256withDSA
SHA256withECDSA
SHA256withRSA
SHA384withECDSA
SHA384withRSA
SHA512withECDSA
SHA512withRSA

如您所见,RSA不是有效的签名算法。
也许NONEwith RSA是你想要的?

 类似资料:
  • 本文向大家介绍详解Java数字签名提供XML安全,包括了详解Java数字签名提供XML安全的使用技巧和注意事项,需要的朋友参考一下 用Java数字签名提供XML安全 众所周知,XML在产品和项目开发中起着非常重要的作用。通过XML文档可以获取很多信息,还可以使用XML文件进行CRUD(增加、查询、更新和 删除)操作。然而值得注意的是,我们如何确保XML中的数据是来自经过认证的可信和可靠的来源。关于

  • 我有java 1.4版本的代码,我们有一个新的要求,比如从另一个webservice响应中解密密码,因此必须使用AES 256解密,得到以下异常: 我试图将jce\U policy\u 1-4版本JAR复制到java home security文件夹中,但仍遇到上述异常 Java 1.4中是否有不更改为1.5的解决方案,因为运行jboss server 3.2.3版将不支持Java 1.5。

  • 问题内容: 这可能是一个荒谬的问题。 我有一个签名的applet,它只能在客户端的计算机文件系统上读写。 我可以从知名机构(例如Verysign或Thawte等)购买数字证书来签署小程序。 如果我使用上述权限对applet进行签名,我可以摆脱Java Plug-in持有的模糊安全性验证吗? 有人在SO中说您可以配置策略文件,而您可以摆脱它。我可以知道吗? 谢谢 问题答案: 摆脱该对话框的最佳方法是

  • 我在JRE 1.8(jdk1.8.0\U 101)上使用SSL从JBoss连接IBM MQ时遇到问题 我在下面一行评论java。安全但无任何变化: 更新:在进行以下更改后,出现如下新错误:TLS\U RSA\U WITH\U AES\U 128\U CBC\U SHA256 JVM参数已添加:-Dcom。ibm。mq。cfg公司。useIBMCipherMappings=false javax.n

  • 问题内容: 我正在尝试在Java + JSF项目中签署对象。 到目前为止,我所做的是创建自己的X509证书以及具有XCA的CA,并将它们都安装在Firefox和Chrome上。 我一直在搜索3天,我如何才能访问它进行签名(如果您安装了多个证书,典型的弹出窗口会要求选择证书),但是我找不到有用的东西。我已经多次看到此代码行: 但是我不知道从哪里可以得到带有证书的请求。 1) 我在哪里可以收到该请求?

  • 问题内容: 我正在使用32位Oracle Java 1.6.0在x86_64 CentOS 5.7上运行tomcat 5.5。 Tomcat使用的JVM进程具有6421 pid。Tomcat运行正常。 运行时失败,并显示: 为了获得任何合理的输出,我需要使用force选项: 该 问题 是: 错误消息 “知名文件不安全” 是什么意思? 什么是“知名”文件? 为什么/何时在没有强制选项的情况下命令不起