使用java android进行签名和验证

时间:2015-05-20 21:05:58

标签: java android rsa digital-signature public-key-encryption

我尝试使用私钥对加密邮件进行签名,并使用Java验证它。这是我第一次使用加密和签名,所以我不确定它应该如何工作,我有点卡在这里。验证始终返回false。

我在这里发布的代码包括最重要的部分:

import android.util.Base64;
import android.util.Log;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

public class SignatureTest {

// testing signature
PublicKey javaPublicKey;
PrivateKey javaPrivateKey;

String message = "Hello world";


public void test() {

    try {
        GenerateKeys();
        byte[] messageBytes = message.getBytes("UTF-8");
        byte[] signature = rsaSign(messageBytes);
        boolean success = rsaVerify(messageBytes, signature);

        if(success){
            Log.e("yay", "yay");
        }
        else {
            Log.e("nay", "nay");
        }


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

}

public void GenerateKeys() {

    SecureRandom random = null;
    try {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        random = SecureRandom.getInstance("SHA1PRNG");
        keyGen.initialize(1024, random);

        KeyPair pair = keyGen.generateKeyPair();

        javaPrivateKey = pair.getPrivate();
        javaPublicKey = pair.getPublic();

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

public byte[] rsaSign (byte[] data) {

    byte[] cipherData = null;

    try {

        Signature s = Signature.getInstance("SHA1withRSA");
        s.initSign(javaPrivateKey);

        s.update(data);

        Log.e("s.sign()", Base64.encodeToString(s.sign(), Base64.DEFAULT));


        return s.sign();


    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (SignatureException e) {
        e.printStackTrace();
    }

    return cipherData;
}

public boolean rsaVerify (byte[] data, byte[] signature) {

    boolean success = false;

    try {

        Signature s = Signature.getInstance("SHA1withRSA");
        s.initVerify(javaPublicKey);

        s.update(data);

        success = s.verify(Base64.decode(signature, Base64.DEFAULT));

        if(success == true) {
            Log.i("yeay", "yay");
        }
        else {
            Log.i("nay", "nay");
        }

        return success;


    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (SignatureException e) {
        e.printStackTrace();
    }

    return false;
}
}

谁能告诉我我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

if (indexPath.row == 1) { UISwitch *switchBtn = [[UISwitch alloc] initWithFrame:CGRectMake(200, 10, 150, 50)]; [switchBtn setOn:YES animated:YES]; NSInteger row; switchBtn.tag=row; row =[indexPath row]; [switchBtn addTarget:self action:@selector(switchStateChanged:) forControlEvents:UIControlEventValueChanged]; cell.accessoryView = switchBtn; [cell addSubview:switchBtn]; UILabel *lblPhone =[[UILabel alloc]initWithFrame:CGRectMake(5, 5, 230, 30)]; lblPhone.text = @"Change Default View as Month View"; lblPhone.font = [UIFont systemFontOfSize:12]; [cell.contentView addSubview:lblPhone]; } -(IBAction)switchStateChanged:(id)sender { UISwitch *switchState = sender; if(switchState.tag == 0) { NSLog(@"ON"); } else { NSLog(@"OFF"); } } 方法中,请在第rsaSign行之后执行以下操作,

s.update(data);

请记住,对byte[] signature = s.sign(); Log.e("s.sign()", Base64.encodeToString(signature , Base64.DEFAULT)); return signature; 方法的调用会将签名对象重置为之前通过调用initSign(PrivateKey)初始化以进行签名时所处的状态。也就是说,如果需要,通过新的更新和签名调用,对象被重置并可用于从同一签名者生成另一个签名。
现在,在sign()方法中,替换该行
rsaVerify
用,
success = s.verify(Base64.decode(signature, Base64.DEFAULT));