title: Digital Signature in java / android (RSA keys)
body: <p>I would like to generate a digital signature in my java/android project with a private key(RSA) stored in DB. </p>
  
  <p>My 2 keys was generated with the below code (<em>project is in production and I cannot change it</em>):</p>
  
  <pre><code>// Get keys pair (RSA)
  KeyPair rsaKyePair = createKeyPair();
  
  // Get private/ public keys and store them in DB
  String pri = getPrivateKeyBase64Str(rsaKyePair);
  String pub = getPublicKeyBase64Str(rsaKyePair));
  
  
  public static KeyPair createKeyPair() {
      KeyPair keyPair = null;
  
      try {
          KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
          keygen.initialize(KEY_LENGTH);
          keyPair = keygen.generateKeyPair();
      } catch (NoSuchAlgorithmException e) {
          e.printStackTrace();
          return null;
      }
      return keyPair;
  }
  
  public static String getPrivateKeyBase64Str(KeyPair keyPair){
      if (keyPair == null) return null;
      return getBase64StrFromByte(keyPair.getPrivate().getEncoded());
  }
  
  public static String getPublicKeyBase64Str(KeyPair keyPair){
      if (keyPair == null) return null;
      return getBase64StrFromByte(keyPair.getPublic().getEncoded());
  }
  
  public static String getBase64StrFromByte(byte[] key){
      if (key == null || key.length == 0) return null;
      return new String(Base64.encode(key));
  }
  </code></pre>
  
  <p>Based on different sites (<a href="https://stackoverflow.com/questions/9755057/converting-strings-to-encryption-keys-and-vice-versa-java">here</a> and <a href="http://www.java2s.com/Tutorial/Java/0490__Security/SimpleDigitalSignatureExample.htm" rel="nofollow noreferrer">here</a>), I'll try to write code for generate a signature:</p>
  
  <pre><code>String mySignature = getDigitalSignature("my_string_", "my_private_string" );
  
  /*
   * Generated a signed String
   * @param text : string to sign
   * @param strPrivateKey : private key (String format)
   */
  public String getDigitalSignature(String text, String strPrivateKey)  {
  
      try {
  
          // Get private key from String
          PrivateKey pk = loadPrivateKey(strPrivateKey);
  
          // text to bytes
          byte[] data = text.getBytes("UTF8");
  
          // signature
          Signature sig = Signature.getInstance("MD5WithRSA");
          sig.initSign(pk);
          sig.update(data);
          byte[] signatureBytes = sig.sign();
  
          return javax.xml.bind.DatatypeConverter.printBase64Binary(signatureBytes);
  
      }catch(Exception e){
          return null;
      }
  
  }
  
  
  
  private PrivateKey loadPrivateKey(String key64) throws GeneralSecurityException {
      byte[] clear = Base64.decode(key64, Base64.DEFAULT);
      PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(clear);
      KeyFactory fact = KeyFactory.getInstance("RSA");
      PrivateKey priv = fact.generatePrivate(keySpec);
      Arrays.fill(clear, (byte) 0);
      return priv;
  }
  </code></pre>
  
  <p>For verify the signature, I use this code in my java API :</p>
  
  <pre><code>/*
   * Verify signature of a string
   * @param signature : signature
   * @param origina: original string to verify
   * @param publicKey: user public key 
   */
  public static boolean verfiySignature(String signature, String original, String publicKey){
  
      try{
  
          // Get private key from String
          PublicKey pk = loadPublicKey(publicKey);
  
          // text to bytes
          byte[] originalBytes = original.getBytes("UTF8");
  
          //signature to bytes
          //byte[] signatureBytes = signature.getBytes("UTF8");
          byte[] signatureBytes =javax.xml.bind.DatatypeConverter.parseBase64Binary(signature);
  
          Signature sig = Signature.getInstance("MD5WithRSA");
          sig.initVerify(pk);
          sig.update(originalBytes);
  
          return sig.verify(signatureBytes);
  
      }catch(Exception e){
          e.printStackTrace();
          Logger log = Logger.getLogger(RsaCipher.class);
          log.error("error for signature:" + e.getMessage());
          return false;
      }
  
  }
  
  
  /*
   * Generate a PublicKey object from a string
   * @ key64 : public key in string format (BASE 64)
   */
  private static PublicKey loadPublicKey(String key64) throws GeneralSecurityException {
      byte[] data = javax.xml.bind.DatatypeConverter.parseBase64Binary(key64);
      X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
      KeyFactory fact = KeyFactory.getInstance("RSA");
      return fact.generatePublic(spec);
  }
  </code></pre>
  
  <p>I've run this code with real data, but the "verifySignature" always returns "False".</p>
  
  <p>I am a newbie in Encryption world, forgive me for my dirty code.</p>
  
  <p>--- EDIT</p>
  
  <p>I got an exception when the verify method is called:</p>
  
  <blockquote>
    <p>java.security.SignatureException: Signature encoding error</p>
  </blockquote>