首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >兼容Android和C#的加密

兼容Android和C#的加密
EN

Stack Overflow用户
提问于 2010-01-19 11:00:50
回答 5查看 22.4K关注 0票数 20

我已经找到了很多如何在C#中进行加密的例子,还有几个适用于安卓的例子,但我特别在寻找一种处理加密的方法(使用AES,TripleDES等)。最终在C#中被解密。我在Android中找到了example for encoding AES,在C#中找到了encoding/decoding AES,但不确定它们是否兼容(C#需要IV,在Android示例中没有为此指定任何内容)。此外,还推荐了一种对加密字符串进行编码以便通过HTTP传输的好方法(Base64?)会很有帮助。谢谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-02-06 15:26:50

http://oogifu.blogspot.com/2009/01/aes-in-java-and-c.html那里得到了一些帮助。

下面是我的Java类:

package com.neocodenetworks.smsfwd;

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import android.util.Log;

public class Crypto {
    public static final String TAG = "smsfwd";

    private static Cipher aesCipher;
    private static SecretKey secretKey;
    private static IvParameterSpec ivParameterSpec;

    private static String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";
    private static String CIPHER_ALGORITHM = "AES";
    // Replace me with a 16-byte key, share between Java and C#
    private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

    private static String MESSAGEDIGEST_ALGORITHM = "MD5";

    public Crypto(String passphrase) {
        byte[] passwordKey = encodeDigest(passphrase);

        try {
            aesCipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "No such algorithm " + CIPHER_ALGORITHM, e);
        } catch (NoSuchPaddingException e) {
            Log.e(TAG, "No such padding PKCS5", e);
        }

        secretKey = new SecretKeySpec(passwordKey, CIPHER_ALGORITHM);
        ivParameterSpec = new IvParameterSpec(rawSecretKey);
    }

    public String encryptAsBase64(byte[] clearData) {
        byte[] encryptedData = encrypt(clearData);
        return net.iharder.base64.Base64.encodeBytes(encryptedData);
    }

    public byte[] encrypt(byte[] clearData) {
        try {
            aesCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
        } catch (InvalidKeyException e) {
            Log.e(TAG, "Invalid key", e);
            return null;
        } catch (InvalidAlgorithmParameterException e) {
            Log.e(TAG, "Invalid algorithm " + CIPHER_ALGORITHM, e);
            return null;
        }

        byte[] encryptedData;
        try {
            encryptedData = aesCipher.doFinal(clearData);
        } catch (IllegalBlockSizeException e) {
            Log.e(TAG, "Illegal block size", e);
            return null;
        } catch (BadPaddingException e) {
            Log.e(TAG, "Bad padding", e);
            return null;
        }
        return encryptedData;
    }

    private byte[] encodeDigest(String text) {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance(MESSAGEDIGEST_ALGORITHM);
            return digest.digest(text.getBytes());
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "No such algorithm " + MESSAGEDIGEST_ALGORITHM, e);
        }

        return null;
    }
}

对于base64编码,我使用了http://iharder.sourceforge.net/current/java/base64/

下面是我的C#类:

using System;
using System.Text;
using System.Security.Cryptography;

namespace smsfwdClient
{
    public class Crypto
    {
        private ICryptoTransform rijndaelDecryptor;
        // Replace me with a 16-byte key, share between Java and C#
        private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

        public Crypto(string passphrase)
        {
            byte[] passwordKey = encodeDigest(passphrase);
            RijndaelManaged rijndael = new RijndaelManaged();
            rijndaelDecryptor = rijndael.CreateDecryptor(passwordKey, rawSecretKey);
        }

        public string Decrypt(byte[] encryptedData)
        {
            byte[] newClearData = rijndaelDecryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
            return Encoding.ASCII.GetString(newClearData);
        }

        public string DecryptFromBase64(string encryptedBase64)
        {
            return Decrypt(Convert.FromBase64String(encryptedBase64));
        }

        private byte[] encodeDigest(string text)
        {
            MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] data = Encoding.ASCII.GetBytes(text);
            return x.ComputeHash(data);
        }
    }
}

我真的希望这对其他人有帮助!

票数 41
EN

Stack Overflow用户

发布于 2010-07-25 15:28:09

在提供的c#源代码示例中,请注意这一行:

Encoding.ASCII.GetString(newClearData);

UTF-8是Android的默认编码,所以加密后的字符串(特别是非ASCII码,比如中文)会被传递给C#,假设UTF-8。如果使用ASCII编码将文本解码回字符串,则文本将变得混乱。这里有一个更好的,

Encoding.UTF8.GetString(newClearData);

谢谢!

票数 4
EN

Stack Overflow用户

发布于 2010-01-19 11:07:49

是的,这应该是好的,只要我们的密钥大小是相同的- 128位AES和正确的块密码模式(CBC)。您可能会遇到填充的问题,但这应该很容易解决。最近,我在使用Java和Python时遇到了这些问题,但最终一切都正常了。在超文本传输协议上编码的Base64应该没问题。祝好运!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2090765

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档