9

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

                }
            }


    }

}

4 Answers 4

15

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?

Sign up to request clarification or add additional context in comments.

Comments

6

Please always refer to the documentation enter image description here

Documentation

Comments

3

I've checked the algorithms supported by java versions(1.7) & (1.8) in my machine. One of my project runs on jdk 1.7.0_80, which doesn't support SHA224withRSA algorithm, if you're in same situation then upgrade to newer version of java atleast to (Java SE 7 Update 131)as I've read it should have similar algorithms as java 8. If no option to update java then try adding org.bouncycastle bcprov-jdk15on maven dependency in pom or a jar file to your project & also in java code add where you build SSLContext/HttpClient include below line:

Security.addProvider(new BouncyCastleProvider());

Also tried installing Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7, but it hasn't worked !!

Comments

1

Specify a valid algorithm. The hash algorithm needs to be specified. For example, SHA256withRSA.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.