public synchronized String generateSignature(byte[] message) throws Exception {
    // Log.trace("Signed message length is " + message.length);

    try {
      digest.reset();
      cipher.init(true, privateRsaKey);
      digest.update(message, 0, message.length);
      byte[] hash = new byte[digest.getDigestSize()];
      digest.doFinal(hash, 0);
      DigestInfo info = new DigestInfo(new AlgorithmIdentifier(md5, null), hash);
      byte[] bytes = info.getEncoded(ASN1Encoding.DER);
      byte[] signature = cipher.processBlock(bytes, 0, bytes.length);
      return new String(org.bouncycastle.util.encoders.Base64.encode(signature));
    } catch (Exception e) {
      throw new Exception("Ошибка создания подписи:\n" + e.getMessage());
    }
  }
 public synchronized void verifySignature(byte[] message, byte[] signature) throws Exception {
   try {
     digest.reset();
     cipher.init(false, publicRsaKey);
     digest.update(message, 0, message.length);
     byte[] hash = new byte[digest.getDigestSize()];
     digest.doFinal(hash, 0);
     DigestInfo info = new DigestInfo(new AlgorithmIdentifier(md5, null), hash);
     byte[] bytes = info.getEncoded(ASN1Encoding.DER);
     byte[] signatureData = org.bouncycastle.util.encoders.Base64.decode(signature);
     byte[] result = cipher.processBlock(signatureData, 0, signatureData.length);
     if ((result == null) || (result.length < hash.length)) {
       throw new Exception("Invalid signature (1)!");
     }
     if (!compareFromTheEnd(hash, result)) {
       throw new Exception("Invalid signature (2)!");
     }
   } catch (Exception e) {
     throw new Exception("Error checking signature:\n" + e.getMessage());
   }
 }