C#中DES加密问题

qv2003 2013-10-11 05:00:03
C#要使用DES加密,但在网上搜的都是加密后转换为BASE64编码,我不需要转换为BASE64编码的格式。只要加密,完成后返回加密字符串。不要类似string str = Convert.ToBase64String(ms.ToArray());的东西。如果加密后在网上解密通过,高分相送。验证网站http://app.baidu.com/app/enter?appid=212407
...全文
239 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
qv2003 2013-10-12
  • 打赏
  • 举报
回复
对应的java解密如下,测试通过 public static String decode(String data, String key) throws Exception { Cipher deCipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(desKeySpec); IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8")); deCipher.init(Cipher.DECRYPT_MODE, secretKey, iv); //BASE64Decoder base64Decoder = new BASE64Decoder(); //byte[] pasByte = deCipher.doFinal(base64Decoder.decodeBuffer(data)); byte[] pasByte = deCipher.doFinal((hexToBytes(data))); return new String(pasByte, "UTF-8"); } public static byte[] hexToBytes(String hexString) { if (hexString == null || hexString.equals("")) { return null; } hexString = hexString.toUpperCase(); int length = hexString.length() / 2; char[] hexChars = hexString.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } private static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); }
qv2003 2013-10-12
  • 打赏
  • 举报
回复
public static string EncryptDES(string encryptString, string encryptKey) { using (DESCryptoServiceProvider des = new DESCryptoServiceProvider()) { byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString); des.Key = UTF8Encoding.UTF8.GetBytes(encryptKey);// ASCIIEncoding.ASCII.GetBytes(encryptKey); des.IV = UTF8Encoding.UTF8.GetBytes(encryptKey); System.IO.MemoryStream ms = new System.IO.MemoryStream(); using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); cs.Close(); } StringBuilder ret = new StringBuilder(); foreach (byte b in ms.ToArray()) { ret.AppendFormat("{0:x2}", b); } ret.ToString(); return ret.ToString(); } } /// <summary> /// DES解密字符串 /// </summary> /// <param name="decryptString">待解密的字符串</param> /// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param> /// <returns>解密成功返回解密后的字符串,失败返源串</returns> //解密方法 public static string DecryptDES(string decryptString, string skey) { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); //put the input string into the byte array byte[] inputbytearray = new byte[decryptString.Length / 2]; for (int x = 0; x < decryptString.Length / 2; x++) { int i = (Convert.ToInt32(decryptString.Substring(x * 2, 2), 16)); inputbytearray[x] = (byte)i; } //建立加密对象的密钥和偏移量,此值重要,不能修改 des.Key = UTF8Encoding.UTF8.GetBytes(skey); des.IV = UTF8Encoding.UTF8.GetBytes(skey); MemoryStream ms = new MemoryStream(); CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write); //flush the data through the crypto stream into the memory stream cs.Write(inputbytearray, 0, inputbytearray.Length); cs.FlushFinalBlock(); //get the decrypted data back from the memory stream //建立stringbuild对象,createdecrypt使用的是流对象,必须把解密后的文本变成流对象 StringBuilder ret = new StringBuilder(); return Encoding.UTF8.GetString(ms.ToArray(),0,ms.ToArray().Length); }
qv2003 2013-10-12
  • 打赏
  • 举报
回复
自己搞定了,多谢各位回复
rtdb 2013-10-11
  • 打赏
  • 举报
回复
引用 4 楼 qldsrx 的回复:
[quote=引用 3 楼 rtdb 的回复:] [quote=引用 1 楼 rtdb 的回复:] 这提问太弱了,不用BASE64编码,加密结果怎么转字符串? 那个工具我看了,人家的加密结果也是BASE64编码的
不好意思,打眼了,那瓜是BASE16编码,不是BASE64[/quote] BASE16编码?你自创的编码吗?居然还升到了星星,混来的吧。人家的是直接16进制表示法显示字节内容而已。 楼主的要求不合理,如果单纯要求加密解密算法是可以给出,但是要猜那个验证网站使用的字符编码则很麻烦。加密解密都是对二进制字节处理的,这就需要Encoding进行编码处理,一般会用Utf8,但是那个网站显然不是,编码种类很多,你让我去猜啊。[/quote] RFC 4648 - The Base16, Base32, and Base64 Data Encodings
qldsrx 2013-10-11
  • 打赏
  • 举报
回复
补充下那个在线工具的js调用代码:
function encode() {
    var v = $("#key").val();
    var d = $("#res").val();
    if (v && v.length == 8) {
        if (d) {
            DES.init(v, encodeURIComponent(d));
            $("#res").val(DES.Encrypt())
        } else {
            alert("请输入需要加密的内容");
        }
    } 
    else {
        alert("请输入正确长度的密码: 长度要求为8位");
    }
}
function decode() {
    var v = $("#key").val();
    var d = $("#res").val();
    if (v && v.length == 8) {
        if (d) {
            DES.init(v, d);
            $("#res").val(decodeURIComponent(DES.Encrypt("Decrypt")))
Uncaught URIError: URI malformed (repeated 2 times)
        } else {
            alert("请输入需要解密的内容");
        }
    } 
    else {
        alert("请输入正确长度的密码: 长度要求为8位");
    }
}
qldsrx 2013-10-11
  • 打赏
  • 举报
回复
这是那个网站所使用的加密算法,由于是js的,算法完全透明,但是和.NET的算法是完全不一样的,虽然都是可以加密解密,但是如果.NET的内置算法加密,在让js的算法解密是肯定不行的,除非将此算法翻译过来。

var DES = {
    // initial permutation IP
    IP_Table: [
        58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 
        62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 
        57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 
        61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
    ],
    // final permutation IP^-1 
    IPR_Table: [
        40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 
        38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 
        36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 
        34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
    ],
    // permuted choice table (key) 
    PC1_Table: [
        57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 
        10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 
        63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 
        14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
    ],
    // permuted choice key (table) 
    PC2_Table: [
        14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 
        23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 
        41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 
        44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
    ],
    // number left rotations of pc1 
    LOOP_Table: [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1],
    // expansion operation matrix
    E_Table: [
        32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 
        8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 
        16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 
        24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1
    ],
    // 32-bit permutation function P used on the output of the S-boxes 
    P_Table: [16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 
        2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25],

    // The (in)famous S-boxes 
    S_Box: [
        // S1 
        [[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7], 
            [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8], 
            [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0], 
            [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]], 
        // S2 
        [[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10], 
            [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5], 
            [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15], 
            [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]], 
        // S3 
        [[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8], 
            [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1], 
            [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7], 
            [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]], 
        // S4 
        [[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15], 
            [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9], 
            [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4], 
            [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]], 
        // S5 
        [[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9], 
            [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6], 
            [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14], 
            [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]], 
        // S6 
        [[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11], 
            [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8], 
            [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6], 
            [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]], 
        // S7 
        [[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1], 
            [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6], 
            [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2], 
            [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]], 
        // S8 
        [[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7], 
            [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2], 
            [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8], 
            [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]]
    ],
    Oct2Bin: ["0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", 
        "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"],
    //str 为八位的字符
    subKeys: new Array(16),
    key: "",
    text: ""
};

DES.init = function(key, text) {
    if (key != this.key) {
        this.key = key;
        this.GenSubKey();
    }
    this.text = text + "        ".substring(0, parseInt("07654321".charAt(text.length % 8), 10));
};

DES.GenSubKey = function() {
    var arr = this.Permute(this.Byte2Bit(this.key), this.PC1_Table);
    var AL = arr.slice(0, 28);
    var AR = arr.slice(28, 56);
    for (var i = 0; i < 16; i++) {
        for (var j = 0, k = this.LOOP_Table[i]; j < k; j++) {
            AL.push(AL.shift());
            AR.push(AR.shift());
        }
        this.subKeys[i] = this.Permute(AL.concat(AR), this.PC2_Table);
    }
};
//数组ar存储二进制数据,该函数将从头开始的每八位转换成对应的字符
DES.Bit2Byte = function(ar, fCh) {
    var str = "";
    if (fCh == "byte") {
        var tmpAr = ar.join("").match(/.{8}/g);
        for (var i = 0, j = tmpAr.length; i < j; i++)
            str += String.fromCharCode(parseInt(tmpAr[i], 2));
    } 
    else if (fCh == "hex") {
        var tmpAr = ar.join("").match(/.{4}/g);
        for (var i = 0, j = tmpAr.length; i < j; i++)
            str += "0123456789abcdef".charAt(parseInt(tmpAr[i], 2));
    } 
    else
        return "Error:Second param is wrong.";
    return str;
};
//将字符串转换成二进制数组
DES.Byte2Bit = function(str) {
    for (var i = 0, j = 8 * str.length, ar = [], ch = ""; i < j; i++) {
        var k = 7 - i % 8;
        if (k == 7)
            ch = str.charCodeAt(parseInt(i / 8, 10));
        ar.push((ch >> k) & 1);
    }
    return ar;
};

//将16进制字符串转变成二进制数组
DES.Hex2Bin = function(str) {
    for (var i = 0, j = str.length, s = ""; i < j; i++)
        s += this.Oct2Bin[parseInt(str.charAt(i), 16)];
    return s.split("");
};

DES.Xor = function(A, B) {
    for (var i = 0, j = B.length, rtn = new Array(j); i < j; i++)
        rtn[i] = A[i] ^ B[i];
    return rtn;
}

DES.Permute = function(ar, tb) {
    for (var i = 0, j = tb.length, rtn = new Array(j); i < j; i++)
        rtn[i] = ar[tb[i] - 1];
    return rtn;
};

DES.F_func = function(Ri, Ki) 
{
    return this.Permute(this.S_func(this.Xor(this.Permute(Ri, this.E_Table), Ki)), this.P_Table);
};
//ar为输入48位串数组
DES.S_func = function(ar) {
    for (var i = 0, arRtn = []; i < 8; i++) {
        var x = i * 6;
        var j = parseInt("" + ar[x] + ar[x + 5], 2);
        var k = parseInt(ar.slice(x + 1, x + 5).join(""), 2);
        arRtn = arRtn.concat(this.Oct2Bin[this.S_Box[i][j][k]].split(""));
    }
    return arRtn;
}

//mode参数为处理模式."Encrypt":加密 "Decrypt":解密,默认为加密
DES.Encrypt = function(mode) {
    mode = mode ? mode : "Encrypt";
    if (mode == "Decrypt")
        var plainTextAr = this.Hex2Bin(this.text).join("").match(/.{64}/g);
    else
        var plainTextAr = this.Byte2Bit(this.text).join("").match(/.{64}/g);
    for (var i = 0, j = plainTextAr.length; i < j; i++) {
        var arr = this.Permute(plainTextAr[i].split(""), this.IP_Table)
        var AL = arr.slice(0, 32);
        var AR = arr.slice(32, 64);
        if (mode == "Decrypt") {
            for (var k = 15; k > -1; k--) {
                var tmp = AR.slice(0, 32);
                AR = this.Xor(this.F_func(AR, this.subKeys[k]), AL);
                AL = tmp;
            }
        } 
        else {
            for (var k = 0; k < 16; k++) {
                var tmp = AR.slice(0, 32);
                AR = this.Xor(this.F_func(AR, this.subKeys[k]), AL);
                AL = tmp;
            }
        }
        plainTextAr[i] = this.Bit2Byte(this.Permute(AR.concat(AL), this.IPR_Table), (mode == "Decrypt" ? "byte" : "hex"));
    }
    return plainTextAr.join("").trim();
}
String.prototype.trim = function() {
    return this.replace(/\s+$/g, "");
}
moonwrite 2013-10-11
  • 打赏
  • 举报
回复
引用 4 楼 qldsrx 的回复:
[quote=引用 3 楼 rtdb 的回复:] [quote=引用 1 楼 rtdb 的回复:] 这提问太弱了,不用BASE64编码,加密结果怎么转字符串? 那个工具我看了,人家的加密结果也是BASE64编码的
不好意思,打眼了,那瓜是BASE16编码,不是BASE64[/quote] BASE16编码?你自创的编码吗?居然还升到了星星,混来的吧。人家的是直接16进制表示法显示字节内容而已。 楼主的要求不合理,如果单纯要求加密解密算法是可以给出,但是要猜那个验证网站使用的字符编码则很麻烦。加密解密都是对二进制字节处理的,这就需要Encoding进行编码处理,一般会用Utf8,但是那个网站显然不是,编码种类很多,你让我去猜啊。[/quote] 既然是选择对称加密,那么解密后还是用人类看得懂的字符把~~~ 16进制什么的~~太高深了~
qldsrx 2013-10-11
  • 打赏
  • 举报
回复
引用 3 楼 rtdb 的回复:
[quote=引用 1 楼 rtdb 的回复:] 这提问太弱了,不用BASE64编码,加密结果怎么转字符串? 那个工具我看了,人家的加密结果也是BASE64编码的
不好意思,打眼了,那瓜是BASE16编码,不是BASE64[/quote] BASE16编码?你自创的编码吗?居然还升到了星星,混来的吧。人家的是直接16进制表示法显示字节内容而已。 楼主的要求不合理,如果单纯要求加密解密算法是可以给出,但是要猜那个验证网站使用的字符编码则很麻烦。加密解密都是对二进制字节处理的,这就需要Encoding进行编码处理,一般会用Utf8,但是那个网站显然不是,编码种类很多,你让我去猜啊。
rtdb 2013-10-11
  • 打赏
  • 举报
回复
引用 1 楼 rtdb 的回复:
这提问太弱了,不用BASE64编码,加密结果怎么转字符串? 那个工具我看了,人家的加密结果也是BASE64编码的
不好意思,打眼了,那瓜是BASE16编码,不是BASE64
feiyun0112 2013-10-11
  • 打赏
  • 举报
回复
BitConverter.ToString(ms.ToArray()).Replcae("-","")

*****************************************************************************
http://feiyun0112.cnblogs.com/
rtdb 2013-10-11
  • 打赏
  • 举报
回复
这提问太弱了,不用BASE64编码,加密结果怎么转字符串? 那个工具我看了,人家的加密结果也是BASE64编码的

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧