使用rsa进行客户端加密和服务器端解密

时间:2014-07-11 13:29:01

标签: java android encryption client

我正在开发一个Android应用程序,我必须使用rsa(公钥)加密一些数据(String)并解密服务器端的加密数据。

我加密后得到一个byte []数组。 我使用base64encoding(android.util.Base64)转换字节数组,默认填充。 然后在服务器端再次使用org.apache.commons.codec.binary.Base64类将字符串转换为byte []。

现在我总是将解密数据作为NULL。

我认为在byte [] - > String和String-> byte []转换中存在问题。

我在使用org.apache.commons.codec.binary.Base64时遇到问题,因为这个软件包的某些版本已包含在android库中。 当我尝试使用org.apache.commons.codec.binary.Base64作为单独的java代码进行编码和解码时。一切正常。

我该如何正确地做到这一点?

android(客户端)上的代码是,

package com.example.rsaclienttest;



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;





import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Base64;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {


    String encSs="";
    String content="";
    String SSkey="";
    byte[] enc;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button submit = (Button)findViewById(R.id.buttonRSA);


        submit.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {


                //Generating key (128 bit) . 

                 String seed="password";

                 Generator obj = new Generator(seed);
                try
                {
                 SSkey=obj.generate(); //right now i'll give only ss directly as i am having some problem with implementatin of rsa .



                 //now encrypt the sskey using rsa ..

                 rsa obj1 = new rsa();
                 enc = obj1.execute(getApplicationContext(), " hello ");
                 encSs = Base64.encodeToString(enc,Base64.DEFAULT);

                 //Toast.makeText(getApplicationContext(), SSkey +"\n"+encSs, Toast.LENGTH_LONG).show();


                new LongOperation().execute("http://192.168.43.164:8080/rsaClient/rsaClient");


                }catch(Exception e){
                 e.printStackTrace();
                }


            }
        });
    }

    private class LongOperation extends AsyncTask<String ,Void,Void>
    {


        private ProgressDialog dialog = new ProgressDialog(MainActivity.this);// creating a progress dialog ..
        private String error=null;
        private final HttpClient client =new DefaultHttpClient();


        protected void onPreExecute()
        {
            dialog.setMessage("Sending key to AS . Please wait ! ");
            dialog.show();
        }

        @Override
        protected Void doInBackground(String... urls) {

            BufferedReader reader = null;

            // Creating HTTP client

            HttpClient httpClient = new DefaultHttpClient();
            // Creating HTTP Post
            HttpPost httpPost = new HttpPost(urls[0]);

            // Building post parameters, key and value pair
            List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(1);
            nameValuePair.add(new BasicNameValuePair("encSS",encSs));



            // Url Encoding the POST parameters
            try {
                httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair));
            }
            catch (UnsupportedEncodingException e) {
                // writing error to Log
                e.printStackTrace();
            }



            // Making HTTP Request
            try {
                    HttpResponse response = httpClient.execute(httpPost);

                    if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK)  //SC_OK =200
                    {   
                    // writing response to log
                    reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
                    String line=reader.readLine();
                    content = "";
                    while(line!=null)
                    {

                        content=content+line ;
                        line=reader.readLine();
                    }

                    reader.close();
                    }
            } catch (ClientProtocolException e) {
                //writing exception to log
                    e.printStackTrace();

            } catch (IOException e) {
                // writing exception to log
                    e.printStackTrace();
            }

            return null;

        }

            protected void onPostExecute(Void unused)
            {

                dialog.dismiss();
                //if(content!="")
                Toast.makeText(getApplicationContext(), content, Toast.LENGTH_LONG).show();


            }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

服务器端的代码是,

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64;

//import sun.misc.BASE64Decoder;

/**
 *
 * @author root
 */
public class rsaClient extends HttpServlet {
    private byte[] decryptedText;

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        try (PrintWriter out = response.getWriter()) {
            /* TODO output your page here. You may use following sample code. */

                InputStream inStream = this.getServletContext().getResourceAsStream("/private.key");
                BufferedReader reader = new BufferedReader(new InputStreamReader(inStream));


                reader.close();

                String encSS = request.getParameter("encSS");

                byte[] decodedBytes = Base64.decodeBase64(encSS);

                ObjectInputStream inputStream = new ObjectInputStream(inStream);
                final PrivateKey privateKey = (PrivateKey) inputStream.readObject();

                 //



                    try {
                    // get an RSA cipher object and print the provider
                    final Cipher cipher = Cipher.getInstance("RSA");

                    // decrypt the text using the private key
                    cipher.init(Cipher.DECRYPT_MODE, privateKey);
                    decryptedText = cipher.doFinal(decodedBytes);

                    } catch (Exception ex) {
                  ex.printStackTrace();
                     }



                 out.println(decryptedText);



        } catch (ClassNotFoundException ex) {
            Logger.getLogger(rsaClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}

服务器上的Logcat:

javax.crypto.BadPaddingException: Decryption error
    at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
    at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:356)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:382)
    at javax.crypto.Cipher.doFinal(Cipher.java:1922)
    at rsaClient.processRequest(rsaClient.java:76)
    at rsaClient.doPost(rsaClient.java:127)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:744)

rsa.java(用于加密):

package com.example.rsaclienttest;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.StreamCorruptedException;
import java.nio.charset.Charset;
import java.security.PublicKey;

import javax.crypto.Cipher;

import android.content.Context;
import android.content.res.AssetManager;
public class rsa{



    public rsa()
    {
        //
    }

    private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");


  /**
   * String to hold name of the encryption algorithm.
   */
  public static final String ALGORITHM = "RSA";

  /**
   * String to hold the name of the public key file.
   */

  public static final String PUBLIC_KEY_FILE = "public.key";



  public static byte[] encrypt(String text, PublicKey key) {
    byte[] cipherText = null;
    try {
      // get an RSA cipher object and print the provider
      final Cipher cipher = Cipher.getInstance(ALGORITHM);
      // encrypt the plain text using the public key
      cipher.init(Cipher.ENCRYPT_MODE, key);
      cipherText = cipher.doFinal(text.getBytes());

    } catch (Exception e) {
      e.printStackTrace();
    }
    return cipherText;
  }

  public byte[] execute(Context context,String originalText) throws StreamCorruptedException, IOException, ClassNotFoundException {


      String s;


      ObjectInputStream inputStream = null;

      // Encrypt the string using the public key
      AssetManager ass = context.getAssets();

      inputStream=new ObjectInputStream(ass.open("public.key"));

      final PublicKey publicKey = (PublicKey) inputStream.readObject();
      final byte[] cipherText = encrypt(originalText, publicKey);
      //return cipherText;

      return cipherText;

      //return s ;
      // byte[] b = s.getBytes(UTF8_CHARSET);



  }
}

0 个答案:

没有答案