【加密算法】RSA(c#、java、php互通)

本文为转载文章,原文地址:http://www.cnblogs.com/FoChen/p/4740814.html

一、摘要

在数据安全上rsa起着非常大的作用,特别是数据网络通讯的安全上。当异构系统在数据网络通讯上对安全性有所要求时,rsa将作为其中的一种选择,此时rsa的互通性就显得尤为重要了。

本文参考网络资料,提供了rsa互通性的一种可行的解决方案(c#,java,php),而这种互通性是在一定的局限性上达成的,比如密钥是1024位的(更高位没试过,应该也可行),基于PKCS1填充方式。

所编写的代码有一部分使用了硬编码,同时注重了功能的实现,在类结构设计上关注不多,有需要的可自行修改重构。

二、生成互通密钥对

重点参考了Jeffrey Walton(http://www.codeproject.com/Articles/25487/Cryptographic-Interoperability-Keys

1、C#

    //生成公私钥对 默认xml格式
    KeyPair keyPair = KeyGenerator.GenerateKeyPair();

    //转换成不同的格式
    KeyPair asnKeyPair = keyPair.ToASNKeyPair(); //ASN格式 java平台惯用
    KeyPair xmlKeyPair = keyPair.ToXMLKeyPair(); //XML格式 c#平台惯用   
    KeyPair pemKeyPair = keyPair.ToPEMKeyPair(); //PEM格式 php平台惯用 PEM格式的密钥格式是PKCS#8

    Console.WriteLine("ASN格式");
    Console.WriteLine(asnKeyPair.PublicKey);
    Console.WriteLine(asnKeyPair.PrivateKey);
    Console.WriteLine("");

    Console.WriteLine("XML格式");
    Console.WriteLine(xmlKeyPair.PublicKey);
    Console.WriteLine(xmlKeyPair.PrivateKey);
    Console.WriteLine("");

    Console.WriteLine("PEM格式");
    Console.WriteLine(pemKeyPair.PublicKey);
    Console.WriteLine(pemKeyPair.PrivateKey);

 2、JAVA

    import cn.ubingo.security.rsa.core.*;
    import cn.ubingo.security.rsa.key.*;

    //生成密钥对
    KeyPair keyPair = KeyGenerator.generateKeyPair();

    //转换成不同的格式
    KeyPair asnKeyPair = keyPair.toASNKeyPair();
    KeyPair xmlKeyPair = asnKeyPair.toXMLKeyPair();
    KeyPair pemKeyPair = xmlKeyPair.toPEMKeyPair();

    //获取公私钥,以asn格式的为例
    String publicKey = asnKeyPair.getPublicKey();
    String privateKey = asnKeyPair.getPrivateKey();

C#密钥生成结果(推荐使用PEM格式的密钥)

三、加密解密

基于三种语言环境都支持的RSA PKCS1填充方式的算法,实现加解密互通

KeyWorker的c#:Encrypt,Decrypt或java:encrypt,decrypt或php:encrypt,decrypt方法实现加解密的功能

1、C#代码

    //ASN
    var publicWorker = new KeyWorker(asnKeyPair.PublicKey, KeyFormat.ASN);  //公钥加密器
    var privateWorker = new KeyWorker(asnKeyPair.PrivateKey, KeyFormat.ASN); //私钥解密器

    //XML
    //var publicWorker = new KeyWorker(xmlKeyPair.PublicKey, KeyFormat.XML);  //公钥加密器
    //var privateWorker = new KeyWorker(xmlKeyPair.PrivateKey, KeyFormat.XML); //私钥解密器

    //PEM
    //var publicWorker = new KeyWorker(pemKeyPair.PublicKey, KeyFormat.PEM);  //公钥加密器
    //var privateWorker = new KeyWorker(pemKeyPair.PrivateKey, KeyFormat.PEM); //私钥解密器

    string plaintext = "你好!世界";

    //加密
    string ciphertext = publicWorker.Encrypt(plaintext);
    Console.WriteLine(ciphertext);

    //解密
    string newPlaintext = privateWorker.Decrypt(ciphertext);
    Console.WriteLine(newPlaintext);

2、JAVA

    import cn.ubingo.security.rsa.core.*;
    import cn.ubingo.security.rsa.data.*;

    //ASN
    KeyWorker privateWorker = new KeyWorker(privateKey, KeyFormat.ASN);
    KeyWorker publicWorker = new KeyWorker(publicKey, KeyFormat.ASN);

    System.out.print(privateWorker.decrypt(publicWorker.encrypt("你好!世界")));
    System.out.print(publicWorker.decrypt(privateWorker.encrypt("你好!中国")));

    //XML
    privateWorker = new KeyWorker(xmlKeyPair.getPrivateKey(), KeyFormat.XML);
    publicWorker = new KeyWorker(xmlKeyPair.getPublicKey(), KeyFormat.XML);

    System.out.print(privateWorker.decrypt(publicWorker.encrypt("你好!世界")));
    System.out.print(publicWorker.decrypt(privateWorker.encrypt("你好!中国")));

    //PEM
    privateWorker = new KeyWorker(pemKeyPair.getPrivateKey(), KeyFormat.PEM);
    publicWorker = new KeyWorker(pemKeyPair.getPublicKey(), KeyFormat.PEM);

    System.out.print(privateWorker.decrypt(publicWorker.encrypt("你好!世界")));
    System.out.print(publicWorker.decrypt(privateWorker.encrypt("你好!中国")));

3、PHP

请保证php文件为utf-8的格式

    include "KeyWorker.php";
    use Cn\Ubingo\Security\RSA\Core as core;
    use Cn\Ubingo\Security\RSA\Data as data;

    /*PEM TEST*/
    $publicWorker = new data\KeyWorker("-----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZw5tyBNJsjgVrPkLUIWF9el5E
    OXL1AydVBnJ/WWPKTZJBWYxudW+1jI5ifML+1DkCxw/2QLowzViV1OLnpNAWr7zv
    LpN6i7OZtq0o2Yfc+vv6vCctTpMvFartRRwDeXTRBgoGd71UwWgdMOu8Gmr9sv5u
    3C9Kj5fhj0I4WgB94wIDAQAB
    -----END PUBLIC KEY-----",core\KeyFormat::PEM);
    $privateWorker = new data\KeyWorker("-----BEGIN PRIVATE KEY-----
    MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJnDm3IE0myOBWs+
    QtQhYX16XkQ5cvUDJ1UGcn9ZY8pNkkFZjG51b7WMjmJ8wv7UOQLHD/ZAujDNWJXU
    4uek0BavvO8uk3qLs5m2rSjZh9z6+/q8Jy1Oky8Vqu1FHAN5dNEGCgZ3vVTBaB0w
    67waav2y/m7cL0qPl+GPQjhaAH3jAgMBAAECgYA6ANHYlv0RuhlNNTVcdCMkhE6f
    CdTVnBTwO/hhFcVRASYUxMT2vhIfuB/WAx5DpqbC53ib+hrCYhPyoVXe8AsWjgBJ
    cj3RHxjLMou0Jbu6mTjcLgKzMYM85yHscmmDcc8l/ep9BhbiJJsTVM8RqqXfdPmY
    5CAgfwsNXruC7Zb5wQJBAMxVZhR+IzoeYLsmEciy2oOaTq5u8O6yjx7RapIggIKT
    dRU5G2GeCyLRHyZH/+U2/nL3undiP74fxizatzgTE3ECQQDApNKzaMobPW23wRes
    E+dDjJxYnqVqOmZS22D6s+BKwDmHpOt+oJmrirY4LWmOUwUfgAboDWH5y/q5+qJH
    P5STAkEAux+F4UR2nDXPnfPKG4L3K8f3QDUm/WGWQcHEF9gd9/Z0JaBrm+TxC8x4
    +0S6ar4HHWASalwWRdWxVchiO770cQJAGaEUAxhq4wreIPdIffU77Em1tziMC0Dv
    whA7q77olSlTvg8b4YHeT+spaPnptCypXtJ6mL7HDSOtHLcSheYYjwJBAJFdK3vg
    ZS0Sk4oy6iOaOcux+5uBkpF9ran0GIpehyGzia+F1Xf/+NnS22qER/ADvRMNnyHf
    QH24qWxQuST39UQ =
    -----END PRIVATE KEY-----",core\KeyFormat::PEM);

    echo $publicWorker->decrypt($privateWorker->encrypt("你好!世界"));
    echo $privateWorker->decrypt($publicWorker->encrypt("你好!中国"));

    /*ASN TEST*/
    $publicWorker = new data\KeyWorker("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZw5tyBNJsjgVrPkLUIWF9el5EOXL1AydVBnJ/WWPKTZJBWYxudW+1jI5ifML+1DkCxw/2QLowzViV1OLnpNAWr7zvLpN6i7OZtq0o2Yfc+vv6vCctTpMvFartRRwDeXTRBgoGd71UwWgdMOu8Gmr9sv5u3C9Kj5fhj0I4WgB94wIDAQAB", core\KeyFormat::ASN);
    $privateWorker = new data\KeyWorker("MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJnDm3IE0myOBWs+QtQhYX16XkQ5cvUDJ1UGcn9ZY8pNkkFZjG51b7WMjmJ8wv7UOQLHD/ZAujDNWJXU4uek0BavvO8uk3qLs5m2rSjZh9z6+/q8Jy1Oky8Vqu1FHAN5dNEGCgZ3vVTBaB0w67waav2y/m7cL0qPl+GPQjhaAH3jAgMBAAECgYA6ANHYlv0RuhlNNTVcdCMkhE6fCdTVnBTwO/hhFcVRASYUxMT2vhIfuB/WAx5DpqbC53ib+hrCYhPyoVXe8AsWjgBJcj3RHxjLMou0Jbu6mTjcLgKzMYM85yHscmmDcc8l/ep9BhbiJJsTVM8RqqXfdPmY5CAgfwsNXruC7Zb5wQJBAMxVZhR+IzoeYLsmEciy2oOaTq5u8O6yjx7RapIggIKTdRU5G2GeCyLRHyZH/+U2/nL3undiP74fxizatzgTE3ECQQDApNKzaMobPW23wResE+dDjJxYnqVqOmZS22D6s+BKwDmHpOt+oJmrirY4LWmOUwUfgAboDWH5y/q5+qJHP5STAkEAux+F4UR2nDXPnfPKG4L3K8f3QDUm/WGWQcHEF9gd9/Z0JaBrm+TxC8x4+0S6ar4HHWASalwWRdWxVchiO770cQJAGaEUAxhq4wreIPdIffU77Em1tziMC0DvwhA7q77olSlTvg8b4YHeT+spaPnptCypXtJ6mL7HDSOtHLcSheYYjwJBAJFdK3vgZS0Sk4oy6iOaOcux+5uBkpF9ran0GIpehyGzia+F1Xf/+NnS22qER/ADvRMNnyHfQH24qWxQuST39UQ=", core\KeyFormat::ASN);

    echo $publicWorker->decrypt($privateWorker->encrypt("你好!世界"));
    echo $privateWorker->decrypt($publicWorker->encrypt("你好!中国"));

编译包:c#(4.0,dll)  java(1.6,jar) php(5.3,php)

源代码:c#(4.0,visual studio 2012)  java(1.6,eclipse 4.4.1) php(5.3,zend studio 12.0)

四、C#代码的简单封装类

/// <summary>
/// RSA加密解密 
/// 基于PKCS1填充 
/// PEM密钥格式为PEM格式的密钥格式是PKCS#8
/// </summary>
public class RsaHelper
{
    /// <summary>
    /// 获取公私钥对
    /// </summary>
    /// <param name="privateKey">私钥</param>
    /// <param name="publicKey">公钥</param>
    /// <param name="keyType">密钥格式</param>
    public static void GetKey(out string privateKey, out string publicKey, KeyType keyType = KeyType.PEM)
    {
        KeyFormat format = GetKeyFormat(keyType);
        KeyPair keyPair = KeyGenerator.GenerateKeyPair(format);

        privateKey = keyPair.PrivateKey;
        publicKey = keyPair.PublicKey;
    }

    /// <summary>
    /// 使用公钥加密
    /// </summary>
    /// <param name="plaintext">明文</param> 
    /// <param name="publicKey">公钥</param>
    /// <param name="keyType">密钥格式</param>
    /// <returns></returns>
    public static string Encrypt(string plaintext, string publicKey, KeyType keyType = KeyType.PEM)
    {
        KeyFormat format = GetKeyFormat(keyType);
        KeyWorker publicWorker = new KeyWorker(publicKey, format);
        return publicWorker.Encrypt(plaintext);
    }

    /// <summary>
    /// 使用私钥解密
    /// </summary>
    /// <param name="ciphertext">密文</param>
    /// <param name="privateKey">私钥</param>
    /// <param name="keyType">密钥格式</param>
    /// <returns></returns>
    public static string Decrypt(string ciphertext, string privateKey, KeyType keyType = KeyType.PEM)
    {
        KeyFormat format = GetKeyFormat(keyType);
        KeyWorker privateWorker = new KeyWorker(privateKey, format);
        return privateWorker.Decrypt(ciphertext);
    }

    /// <summary>
    /// 返回密钥格式
    /// </summary>
    /// <param name="keyType"></param>
    /// <returns></returns>
    private static KeyFormat GetKeyFormat(KeyType keyType)
    {
        switch (keyType)
        {
            case KeyType.ASN:
                return KeyFormat.ASN;
            case KeyType.XML:
                return KeyFormat.XML;
            case KeyType.PEM:
                return KeyFormat.PEM;
            default:
                throw new ArgumentException("无效参数keyType");
        }
    }
}

 

posted @ 2018-12-11 16:32  a boy  阅读(2306)  评论(0编辑  收藏  举报