RSA on Android is different from PC

2019-06-07 19:27发布

问题:

I search a lot but I didn't find the useful answer. I develop java and android security application. I found some problem that when I create RSA key on PC and I transfer RSA public key to android. When I encrypt my data with public key on android and I decrypt the data by using private key on PC, it shows Badpadding Exception. I search on the google on this exception. I found some user that has the same problem to me but the answer is no use. They told me to use Base64 to encode it but the key is still wrong. here is my code.

 public void generateKeys(){
    try {
        KeyPairGenerator generator;
        generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(1024, new SecureRandom());
        KeyPair pair = generator.generateKeyPair();

        pubKey = pair.getPublic();
        privKey = pair.getPrivate();
        //================================================
       System.out.println("My Public KEY "+pubKey.toString());
         System.out.println("My Private KEY "+privKey.toString());

        byte[]pk_byte = pubKey.getEncoded();
        byte[]sk_byte = privKey.getEncoded();

            FileOutputStream keyfos_pub = new FileOutputStream(new File(Environment.getExternalStorageDirectory(),"RSAKey/publicKey.txt"));
            keyfos_pub.write(pk_byte);
            keyfos_pub.close();

            FileOutputStream keyfos_pri = new FileOutputStream(new File(Environment.getExternalStorageDirectory(),"RSAKey/privateKey.txt"));
            keyfos_pri.write(sk_byte);
            keyfos_pri.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

}

When I print out the key, it looks like this.

RSA Private CRT Key
            modulus: dba017a7653612c53f3a46bb99f5098c7bf9012d06f3d20f8f01a67d17aeefd83070a2ff181468679a2d5abae6f7c074b7b3888a4a57533acc3d2d1dfdd86cdc032d3eafd6cf8423edfa3451333bf1d7377352dd3feb9268032831abd72c5c932fed9b4c667f3da062f4beb7a321f2c434d232ee746885dce13a1656eb42fe6b
    public exponent: 10001
   private exponent: 72f10f5019653a5fa6de9e0432e80e4e4ad79fe8ebd99157793598e7a10c7a14000e0310548ee1b14efc6b9ea3a08845cd9a955c22da1f0207c000abd09d83228e05a42f9bd88733afc2a4c1e30770e7ac3c41c55adae734e4f8126da494a88f362d716d6b37a2d7bfbe53824cfb9dc7a0289aa432226bbece49129f47de2a61
             primeP: efa2665a1e08dce4450ad608e17df1e3650ab2cfc44e9b3b6a346611b270b245e21c28f71971d5062368e66b99297085f23104577e529ef08b263e63387cf17b
             primeQ: ea9fde740a15d7f68f5aadb72a588f65da3761119b0c73930f111a43d513d19f42185afcd0291f03a9861a7757108f0e83d4d904ddf541a2debd79344387bbd1
     primeExponentP: 45202ab84a3bb244a2e9fa4dfb861235cf5ae3b3ed63e381a32454613c8127dbe2daceb26103a638ac14418bbe55e6e0acb99910081f9b3bb65824dd08597a6b
     primeExponentQ: 53ca665a90a37e6e1a822ad9e8309a7da871f0a3a5f8cb69b08ece0f7d90476395ea36cc64d6dab1a72032617e6176859b852f3ff2b8bd091a7d164518fce791
     crtCoefficient: 695a3707d033aa2474a7a64959589842099a220540167b48f42bbbd1d786d1a84c378f9a1bc0311948287cbf7669aa44156dd9f24bfe88baf931e5da70a06c4

RSA Public Key
            modulus: dba017a7653612c53f3a46bb99f5098c7bf9012d06f3d20f8f01a67d17aeefd83070a2ff181468679a2d5abae6f7c074b7b3888a4a57533acc3d2d1dfdd86cdc032d3eafd6cf8423edfa3451333bf1d7377352dd3feb9268032831abd72c5c932fed9b4c667f3da062f4beb7a321f2c434d232ee746885dce13a1656eb42fe6b
    public exponent: 10001

I send my key to PC and print out it looks like this

Sun RSA private CRT key, 1024 bits
  modulus:          133510687177139403090984227659818165988216147752229771757259279456909046924729578431711819486905574365970242930474912203422914618872480707080105400973005394104312017850522474151319747965391515392091886771183127658574637486403332621957057719375091145573274843838361168501101321026667287976397870949812555235301
  public exponent:  65537
  private exponent: 9980146428442039393666657480590341260299844482325612277626580558453963728645653672535456363067433797990268399780224833064816191126482490562360748269935354262219600344146818595176602910809143102802601846580823241077395526479491554799584457750285244532837191028964347562514222968145677820868899082320352227173
  prime p:          12299841631131712301068734715117232218530765196368758184959862403767638338760002562429845237522849739220962134079733702092483313582445665328865919334315231
  prime q:          10854667172235374767842313747899047475769598966944705527971116954964144369647441254504149073040778536441723902849901407264741891511747045046848533162966971
  prime exponent p: 9681923647204217071082501281466465900019303827612974308340469989251337818636053102684450861548877311242977166683023364260601327205871598989662862911311993
  prime exponent q: 1654443602597908945419791446477006656323336803344838236704510234877044083623118096514059921732827819407607611968318128037101282547428799502158627916518563
  crt coefficient:  8339065711012644104593134475846199184972354402766421557421676186133596071951423663692155855342215056476322973047333984032026031966395156454879551656339085

It is clear that the key was changed because there is a word "1024 bits" appear in the key and the number of modulas is not the same as well

How can I manage this problem. I'd like a professional to help me please

回答1:

That does look like a different key. Please try again as you've probably send an old key or something. Make sure you don't regenerate the key pair, it will be different each time. Use the private key to print out the modulus as BigInteger instead; BigInteger instances will always print out as decimals making for an easier comparison. Or even better, use BigInteger.toString(16) to get a hexadecimal representation.

If you use a good random number generator (like the default one in Java) then the modulus should be unique for the key pair. Therefore it, or the SHA1 hash over the modulus is normally used to identify the key.



回答2:

They're the same thing, but Android prints it out in base 16 (hexadecimal) whereas your desktop's Java is printing it in base 10 (decimal). You'll see variations of the output of toString() between different implementations.

For instance, look at the public exponent and note that hex 0x10001 is equal to decimal 65537. This exponent is commonly known as RSA F4. However as this public exponent is used for a lot of keys, you cannot use it to distinguish between keys.