如何在Android中使用C#生成的RSA公钥? [英] How do I use a C# generated RSA public key in Android?

查看:37
本文介绍了如何在Android中使用C#生成的RSA公钥?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在无法假定HTTPS可用的情况下,我想确保Android应用程序与C#ASP.NET服务器之间的消息隐私.

I want to ensure message privacy between an Android app and C# ASP.NET server, in a situation where HTTPS can't be assumed to be available.

我想使用RSA加密对称密钥,该对称密钥是在Android设备首次与服务器联系时从其传输的.

I want to use RSA to encrypt a symmetric key which is transferred from the Android device when it first contacts the server.

已在服务器上生成RSA密钥对,并且私钥已保存在服务器上.密钥对是使用以下代码在C#中生成的:

The RSA key pair has been generated on the server and the private key is held on the server. The key pair was generated in C# using:

// Create a new instance of RSACryptoServiceProvider
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048);
// Ensure that the key doesn't get persisted
rsa.PersistKeyInCsp = false;
RSAParameters parameters = rsa.ExportParameters(false);
string modulus = Convert.ToBase64String(parameters.Modulus);
string exponent = Convert.ToBase64String(parameters.Exponent);
string xmlKeys = rsa.ToXmlString(true);

尝试通过硬编码(从Visual Studio复制到Eclipse)嵌入公钥无效.代码抛出org.bouncycastle.crypto.DataLengthException:对于rsaCipher.doFinal()方法调用上的RSA密码输入太大.

Attempting to embed the public key by hard-coding (copying from Visual Studio to Eclipse) doesn't work. The code throws an org.bouncycastle.crypto.DataLengthException: input too large for RSA cipher on the rsaCipher.doFinal() method call.

// Generate a new AES key
byte[] key = null;
try {
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    keygen.init(128);            
    key = keygen.generateKey().getEncoded();
}
catch (NoSuchAlgorithmException e) {}

// Set up modulus and exponent
String mod = "qgx5606ADkXRxndzurIRa5GDxzDYg5Xajeym7I8BXG1HBSzaaGmX+rjQfZK1h4JtQU+Xaowsc81mgJU8+gwneQa56r1bl6/5jFue4FsdXKfpau5az8rY2SAHKcOeyHAOsT9ZqcNa1x6cL/jl9P3cBtOzMk51Hk/w6VNoQ5JJo/0m/eAJzlhVKr2xbOYFhd0xp3qUgRuK8TN4TsSvfc+R1LOWc8+3H22Zj3vhBxSqSgeXxdxi7ThiGiAl6HUwMf8ph7FHNJvoUQq+QPL6dx77pu6xVFiHv1JOfpbKcOubn0VSPLYKY3QPKCzNMYQ6pxUDqzpGtydHR1xaX5K0FGTraw==";

String ex = "AQAB";
BigInteger modulus = new BigInteger(Base64.decode(mod, Base64.DEFAULT));
BigInteger exponent = new BigInteger(Base64.decode(ex, Base64.DEFAULT));

// Encrypt the AES key
PublicKey pubKey;
byte[] cipherData;
try {
    pubKey = KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpe(modulus, exponent));
    Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");     
    rsaCipher.init(Cipher.ENCRYPT_MODE, pubKey);
    // The following line fails with:
    // org.bouncycastle.crypto.DataLengthException
    cipherData = rsaCipher.doFinal(key);     
}
catch (InvalidKeySpecException e) {}
catch (NoSuchAlgorithmException e) {}
catch (InvalidKeyException e) {}
catch (NoSuchPaddingException e) {}
catch (BadPaddingException e) {}
catch (IllegalBlockSizeException e) {}

我怀疑我没有正确解码模数字符串,因为在Android中生成公钥会成功加密密钥.我使用了以下代码:

I suspect that I have decoded the modulus string incorrectly, because generating the public key in Android encrypts the key successfully. I used this code:

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");     
kpg.initialize(1024);     
KeyPair kpa = kpg.genKeyPair();     
pubKey = kpa.getPublic();   

那么,我做错了什么?

推荐答案

尝试使用 new BigInteger(1,模数).BigIntegers是带符号的,并且随着模数从设置为1的第一位开始,它将始终被解释为负数.

Try using new BigInteger(1, modulus). BigIntegers are signed and as the modulus starts with the first bit set to 1, it will always be interpreted as a negative number.

这篇关于如何在Android中使用C#生成的RSA公钥?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆