RSA和AES在c#服务端和android客户端之间的加密解密
2015-06-04 10:19
791 查看
记得去年上半年做了个AES和RSA加密解密的功能,最近又回到了这里。不同的是,今年这同事开始的时候给我的不是cer证书,而是Base64,或者16进制的modules和exponent,然后有点束手无策。[C# Java间进行RSA加密解密交互](http://blog.csdn.net/road2010/article/details/40071843) 后来在网上找到篇文章,参照它的这个方法,是能解,但是我这android手机端,字符串“demon”解出来之后的字符长度一直是76,而c#服务端一直是128。 后来同事找帮忙,生成了一对cer公私密钥证书,然而问题又来了,C#加密解密的长度是344,我这边还是76.不知道是否广大的网友能否帮我解答一下。 现在我将以前写的c#端和android端的RSA和AES加密解密的贴出来,望对大家有所裨益,也算做个记录。
C#
RSA:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace CloudLearn.Tool.Security
{
public static class RSA
{
private static string CERT = “Theoservice”;
private static int KEYLENGTH = 256;
private static int BLOCKSIZE = KEYLENGTH - 11;
static RSA()
{
CERT = SecuritySection.Default.Name;
KEYLENGTH = SecuritySection.Default.Length;
BLOCKSIZE = KEYLENGTH - 11;
}
private static X509Certificate2 GetRSACertificate()
{
X509Certificate2 clientCert = null;
if (clientCert == null)
{
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
foreach (var certificate in store.Certificates)
{
if (certificate.GetNameInfo(X509NameType.SimpleName, false) == CERT)
{
clientCert = certificate;
break;
}
}
}
return clientCert;
}
public static RSACryptoServiceProvider GetPrivateKey()
{
var clientCert = GetRSACertificate();
var publicKey = (RSACryptoServiceProvider)clientCert.PrivateKey;
return publicKey;
}
public static string Encrypt(string rawText)
{
return Encrypt(rawText, GetPrivateKey());
}
///
/// RSA加密
///
///
///
///
public static string Encrypt(string rawText, RSACryptoServiceProvider rsa)
{
byte[] cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(rawText), false);
return Convert.ToBase64String(cipherbytes);
}
public static string Decrypt(string rawText)
{
return Decrypt(rawText, GetPrivateKey());
}
///
/// RSA解密
///
///
///
///
public static string Decrypt(string rawText, RSACryptoServiceProvider rsa)
{
try
{
var encryptedBytes = Convert.FromBase64String(rawText);
int numBlock = encryptedBytes.Length / KEYLENGTH;
byte[] rawResult = new byte[0];
var buffer = new byte[KEYLENGTH];
//var buffer1 = rsa.Decrypt(encryptedBytes, false);
for (var i = 0; i < numBlock; i++)
{
Array.Copy(encryptedBytes, i * KEYLENGTH, buffer, 0, buffer.Length);
var decryptedBytes = rsa.Decrypt(buffer, false);
var resultBuffer = new byte[rawResult.Length + decryptedBytes.Length];
Array.Copy(rawResult, resultBuffer, rawResult.Length);
Array.Copy(decryptedBytes, 0, resultBuffer, rawResult.Length, decryptedBytes.Length);
rawResult = resultBuffer;
}
return Encoding.UTF8.GetString(rawResult); ;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return null;
}
}
}
}
AES:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace CloudLearn.Tool.Security
{
public static class AES
{
public static int Length { get; set; }
static AES()
{
Length = SecuritySection.Default.AESKeyLength;
}
///
/// 有密码的AES加密
///
/// 加密字符
/// 加密的密码
/// 密钥
///
public static string Encrypt(string rawText, string key)
{
byte[] keyArray = Encoding.UTF8.GetBytes(key);//61 97
byte[] toEncryptArray = Encoding.UTF8.GetBytes(rawText);
RijndaelManaged rDel = new RijndaelManaged();
//rDel.BlockSize = 512;
rDel.KeySize = Length * 8;
byte[] iv = new byte[Length];
for (int i = 0; i < Length; i++)
{
iv[i] = 0;
}
rDel.Key = keyArray;
rDel.Mode = CipherMode.ECB;
rDel.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = rDel.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
///
/// AES解密
///
///
///
///
///
public static string Decrypt(string rawText, string key)
{
byte[] keyArray = Encoding.UTF8.GetBytes(key);
byte[] toEncryptArray = Convert.FromBase64String(rawText);
RijndaelManaged rDel = new RijndaelManaged();
rDel.KeySize = Length * 8;
byte[] iv = new byte[Length];
for (int i = 0; i < Length; i++)
{
iv[i] = 0;
}
rDel.IV = iv;
rDel.Key = keyArray;
rDel.Mode = CipherMode.ECB;
rDel.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = rDel.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Encoding.UTF8.GetString(resultArray);
}
}
}
android
RSA
import android.annotation.SuppressLint;
import android.util.Base64;
import android.util.Log;
import com.hbyx.tool.config.Configuration;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.interfaces.RSAPublicKey;
import javax.crypto.Cipher;
public class RSA {
private static Certificate cert;
private static int key_len;
private static Certificate getCert() throws CertificateException { if (cert == null) { //Configuration.def.getSecretRsaCer() //cer证书名称,我是放在RSA加密的同一个包里 cert = CertificateFactory.getInstance("X.509").generateCertificate( RSA.class.getResourceAsStream(Configuration.def .getSecretRsaCer())); key_len = ((RSAPublicKey) cert.getPublicKey()).getModulus() .bitLength() / 16; } return cert; } private static String[] splitString(String string, int len) { // string.split(regularExpression) int x = string.length() / len; int y = string.length() % len; int z = 0; if (y != 0) { z = 1; } String[] strings = new String[x + z]; String str = ""; for (int i = 0; i < strings.length; i++) { if (i == x + z - 1 && y != 0) { str = string.substring(i * len, i * len + y); } else { str = string.substring(i * len, i * len + len); } strings[i] = str; } return strings; } @SuppressLint("TrulyRandom") public static String Encrypt(String str) throws Exception { byte[] dat = new byte[1024 * 20]; int length = 0; try { Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); rsa.init(Cipher.ENCRYPT_MODE, getCert()); // 加密数据长度 <= 模长-11 String[] datas = splitString(str, key_len - 11); // 如果明文长度大于模长-11则要分组加密 for (String s : datas) { for (Byte b : rsa.doFinal(s.getBytes())) { dat[length++] = b; } } return Base64.encodeToString(dat, 0, length, Base64.DEFAULT); } catch (Exception e) { e.printStackTrace(); Log.e("RSA.Encrypt", e.getMessage()); throw e; } }
}
AES:
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class AESCipher {
/*
* 加密
* @param key
* @param src
* @return
* @throws Exception
*/
public static String encrypt(String key, String src) throws Exception {
key = createKey(key);
byte[] rawKey = getRawKey(key.getBytes());
byte[] result = encrypt(rawKey, src.getBytes());
return toHex(result);
}
/*
* 解密
* @param key
* @param encrypted
* @return
* @throws Exception
*/
public static String decrypt(String key, String encrypted) throws Exception {
key = createKey(key);
byte[] rawKey = getRawKey(key.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
private static byte[] getRawKey(byte[] seed) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); // SHA1PRNG 强随机种子算法, 要区别4.2以上版本的调用方法 SecureRandom sr = null; if (android.os.Build.VERSION.SDK_INT >= 17) { sr = SecureRandom.getInstance("SHA1PRNG", "Crypto"); } else { sr = SecureRandom.getInstance("SHA1PRNG"); } sr.setSeed(seed); kgen.init(256, sr); //256 bits or 128 bits,192bits SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); return raw; } private static byte[] encrypt(byte[] key, byte[] src) throws Exception { SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = cipher.doFinal(src); return encrypted; } private static byte[] decrypt(byte[] key, byte[] encrypted) throws Exception { SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); byte[] decrypted = cipher.doFinal(encrypted); return decrypted; } public static String toHex(String txt) { return toHex(txt.getBytes()); } public static String fromHex(String hex) { return new String(toByte(hex)); } public static byte[] toByte(String hexString) { int len = hexString.length()/2; byte[] result = new byte[len]; for (int i = 0; i < len; i++) result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue(); return result; } public static String toHex(byte[] buf) { if (buf == null) return ""; StringBuffer result = new StringBuffer(2*buf.length); for (int i = 0; i < buf.length; i++) { appendHex(result, buf[i]); } return result.toString(); } private final static String HEX = "0123456789ABCDEF"; private static void appendHex(StringBuffer sb, byte b) { sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f)); } public static String createKey(String userId){ String key = ""; for(int i=0;i<16-(userId.length());i++){ key+="0"; } key+=userId; return key; }
}
好了,希望能有好心的网友帮忙回答一下我的问题,RSA加密(“demon”)之后的密文(base64)长度会有多长,能达到344的长度??那手机端发送密文所耗费的流量也太大了吧。。。。。
相关文章推荐
- Android Binder设计与实现 – 设计篇
- Android实战简易教程-第八枪(ImageSwitcher用法实例)
- HTML---Android中webview和js之间的交互
- Android 3G驱动
- Android各版本及API对应关系,持续更新!
- android 开发工具
- 值得推荐的android开源框架
- 最流行的android组件大全
- HTML---android webview组件如何使用 Webview与js交互
- Android学习 - Android优化浅析
- Android---AlertDialog
- android移植ffmpeg的编译
- Android 开发环境下载地址
- ANDROID ONTOUCHEVENT, ONCLICK及ONLONGCLICK的调用机制
- 【Android】SAX解析之错误纠正!!
- 常用的android弹出对话框
- Android开发 学习笔记——HelloWorld
- android中各种颜色在drawable.xml的值
- android中string.xml中%1$s、%1$d等的用法
- android:selector的用法