RSA和AES在c#服务端和android客户端之间的加密解密

记得去年上半年做了个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的长度??那手机端发送密文所耗费的流量也太大了吧。。。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值