![](/img/trans.png)
[英]How to encode a text with rsa/ecb/pkcs1 padding mode with a given public key in java?
[英]What are the differences between C# and Java (Android) when encrypting using RSA with PKCS1 padding?
我正在使用RSA和Java(Android)中的PKCS1填充來加密文本,之后必須將其作為Web服務主體的一部分發送。 我的Java代碼的輸出不起作用,但是如果我在C#中使用技術上相同的算法,那么它可以正常工作。
這是可以正常工作的C#代碼:
static void Main(string[] args)
{
var plainData = "plain_text";
RSA publicKeyEncryptor = getRSAPublic(@"<public_key>");
var plainBytes = Encoding.ASCII.GetBytes(plainData);
string encryptedPayload = System.Convert.ToBase64String(publicKeyEncryptor.Encrypt(plainBytes, RSAEncryptionPadding.Pkcs1));
Console.WriteLine(encryptedPayload);
}
public static RSA getRSAPublic(string publicKey)
{
string publicKeyPem = $"-----BEGIN PUBLIC KEY-----\r\n{ publicKey }\r\n-----END PUBLIC KEY-----\r\n";
var pemReader = new PemReader(new StringReader(publicKeyPem));
AsymmetricKeyParameter keyPairRaw = (AsymmetricKeyParameter)pemReader.ReadObject();
RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)keyPairRaw);
RSA rsaObj = System.Security.Cryptography.RSA.Create();
rsaObj.ImportParameters(rsaParams);
return rsaObj;
}
當我嘗試將其轉換為Java (Android)時,這是我想到的代碼,但未生成有效的輸出:
public static void main(String args[]) {
String stringToEncrypt = "plain_text";
String publicKey = "<public_key>";
System.out.println(encrypt(stringToEncrypt, publicKey))
}
public String encrypt(String plain, String publicKey) {
try {
byte[] keyBytes = Base64.decode(publicKey, Base64.DEFAULT);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
PublicKey rsaPublicKey = KeyFactory.getInstance("RSA").generatePublic(spec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey);
byte[] plainTextBytes = plain.getBytes(Charset.forName("US-ASCII"));
byte[] encryptedBytes = cipher.doFinal(plainTextBytes);
return Base64.encodeToString(encryptedBytes, Base64.NO_WRAP));
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
有什么不同?
謝謝!
Java和C#程序均產生兼容的輸出。 兼容,但不完全相同,因為每次輸出都應該不同。 出於安全原因,PKCS1填充包含隨機成分。 因此,如果您期望相同的輸出,則您的期望是錯誤的。 相同的輸出可能表明出了點問題,每次輸出都應該不同。
RFC 8017的7.2.1節詳細說明了正在發生的事情。 特別是,步驟2a表示:
生成長度為k-mLen-3的八位字節串PS,該字符串由偽隨機生成的非零八位字節組成。 PS的長度至少為八個八位位組。
為了驗證它們的兼容性,我根據您的代碼組成了小型C#和Java程序,發現每個程序都可以解密對方的輸出並獲得正確的結果。
兩種代碼都是正確的。 您可以使用Java版本和C#版本以相同的方式加密數據。 如果其中一個正在工作而另一個在失敗,則可能是您使用了不正確的公鑰(復制/粘貼錯誤,一些不同的字節等)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.