java card的rsa运算_[转载]JAVA中使用P和Q分量计算N和D进行RSA运算

最近在使用Java中需要使用PQ形式的私钥进行RSA加解密运算,本来以为Java中应该很多类似的例子,发现所有的例子都是从ND形式的私钥,竟然没有人用分量P和Q计算N和D进行运算。对Java使用RSA运算不太熟,只能自己一点一点搞了。身边的Java

的仙们,好像身边都没人中国剩余定理,所以也不会遇到P和Q?不管他们了,总结下一个非Java程序员遇到的几个问题。

1.BigInteger类

可以获得大数的二进制补码,如果需要导出BigInteger中的数据,需要忽略符号位,从第二字节开始拷贝,如果从第一字节就拷贝,那么会丢失最后一字节,把符号位存下来。 BigInteger类提供modInverse方法,可以直接求d=e−1modφ(n),这样就省事多了。

2.Cipher类

方法,参数是“算法/模式/填充方式”,因为我只有一块定长128字节数据进行RSA运算,自己进行填充和去填充,按照sun的文档中的说明,填写”RSA/None/NoPadding”,但是编译的时候报错,提示不支持,网上搜了搜,都说默认的Crypt

Provider不支持NoPadding,必须是PKCS#1的填充,感觉很不靠谱啊,后来发现是在Jdk1.7还是哪个版本之后,不支持None的模式,用ECB模式就行了,之前的版本是不是支持None也没去验证。

3.代码

RSACrtUtil.java package com.zhantianzuo.alg;

import java.math.BigInteger; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import

java.security.NoSuchAlgorithmException; import java.security.Security; import

java.security.interfaces.RSAPrivateCrtKey; import

java.security.interfaces.RSAPublicKey; import

java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec;

import javax.crypto.Cipher;

public class RSACrtUtil {

public static final int RSA_MODULUS_LEN = 128;

public static final int RSA_P_LEN = RSA_MODULUS_LEN/2;

public static final int RSA_Q_LEN = RSA_MODULUS_LEN/2;

public static final int publicExponent = 65537;

public static final String KEY_ALGORITHM_MODE_PADDING = "RSA/ECB/NoPadding"; //不填充

public static final String KEY_ALGORITHM = "RSA"; //不填充

public static byte[] prikey_crt_decrypt(byte[] data, byte[] prikey) throws Exception{

byte[] buf_p = new byte[RSA_P_LEN];

byte[] buf_q = new byte[RSA_Q_LEN];

//buf_p[0] = (byte)0x00;

//buf_q[0] = (byte)0x00;

System.arraycopy(prikey, 0, buf_p, 0, RSA_P_LEN);

System.arraycopy(prikey, RSA_P_LEN, buf_q, 0, RSA_Q_LEN);

//

BigInteger p = new BigInteger(1, buf_p);

BigInteger q = new BigInteger(1, buf_q);

BigInteger n = p.multiply(q); //n = p * q

BigInteger p1 = p.subtract(BigInteger.valueOf(1));

BigInteger q1 = q.subtract(BigInteger.valueOf(1));

BigInteger h = p1.multiply(q1);// h = (p-1) * (q-1)

BigInteger e = BigInteger.valueOf(publicExponent);

BigInteger d = e.modInverse(h);

RSAPrivateKeySpec keyspec = new RSAPrivateKeySpec(n, d);

KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

Key privateKey = keyFactory.generatePrivate(keyspec);

Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_MODE_PADDING);

cipher.init(Cipher.DECRYPT_MODE, privateKey);

return cipher.doFinal(data);

}

public static byte[] pubkey_encrypt(byte[] data, byte[] pubkey) throws Exception{

byte[] pubkey_buf = new byte[RSA_MODULUS_LEN+1];//多一字节符号位

pubkey_buf[0] = (byte)0x00;

System.arraycopy(pubkey, 0, pubkey_buf, 1, RSA_MODULUS_LEN);

//

BigInteger e = BigInteger.valueOf(publicExponent);

BigInteger n = new BigInteger(pubkey_buf);

//

RSAPublicKeySpec keyspec = new RSAPublicKeySpec(n, e);

KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

Key publicKey = keyFactory.generatePublic(keyspec);

Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_MODE_PADDING);

cipher.init(Cipher.ENCRYPT_MODE, publicKey);

return cipher.doFinal(data);

}

public static void generateKeyPair(byte[] pubkey, byte[] prikey) throws Exception{

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);

keyPairGenerator.initialize(RSA_MODULUS_LEN*8);

KeyPair keyPair = keyPairGenerator.generateKeyPair();

RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();

RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey)keyPair.getPrivate();

//

BigInteger n = publicKey.getModulus();

BigInteger p = privateKey.getPrimeP();

BigInteger q = privateKey.getPrimeQ();

System.arraycopy(n.toByteArray(), 1, pubkey, 0, 128);

System.arraycopy(p.toByteArray(), 1, prikey, 0, 64);

System.arraycopy(q.toByteArray(), 1, prikey, 64, 64);

//

}

}

Test.java package com.zhantianzuo.alg;

import java.math.BigInteger; import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import

java.security.NoSuchAlgorithmException; import

java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey;

public class Test {

private static final String ALGORITHM = "RSA";

private static final int key_len = 128;

public static void main(String[] args) {

//

byte[] pubkey = new byte[128];

byte[] prikey = new byte[128];

try {

RSACrtUtil.generateKeyPair(pubkey, prikey);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

//

int i;

byte[] plaintext = null;

byte[] ciphertext = null;

byte[] data = new byte[key_len];

for(i=0; i

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值