【问题标题】:Need an Objective-C version of Java Encryption and Base 64 encoding that I already have需要我已经拥有的 Java 加密和 Base 64 编码的 Objective-C 版本
【发布时间】:2010-12-17 21:24:55
【问题描述】:

我有一个 Java 类,它加密一个字符串,然后将其转换为 Base64,用于 Android 应用程序:(此代码用于此示例(请注意超链接中的空格):http://stackoverflow。 com/questions/2090765/encryption-compatable-between-android-and-c)

public class encryption {
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";
//the secret key in HEX is 'secretkey'
private static byte[] rawSecretKey = {Ox73, Ox65, Ox63, Ox72, Ox65, Ox74, Ox6B, Ox65, Ox79};

private static String MESSAGEDIGEST_ALGORITHM = "MD5";

public encryption(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);
}




//base 64 encryption
public String encryptAsBase64(byte[] clearData) {
    byte[] encryptedData = encrypt(clearData);
    return 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;
}

}

base 64 加密来自(注意超链接中的空格)http://iharder.sourceforge.net/current/java/base64/

发生的情况是,这被传递到 C#/.net 服务器进行解密,并且在 Android 上一切正常。现在的问题是将其转换为 Objective-C 以在 iPhone 上使用。

我做了很多研究,最接近的答案是http://dotmac.rationalmind.net/2009/02/aes-interoperability-between-net-and-iphone/

但是,当我使用该示例(直接从下载的 zip 中获取的代码)时,我收到“填充无效且无法删除”。错误服务器端。

我的服务器端代码是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

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

namespace test.Business
{
    public class Crypto
    {
        private ICryptoTransform rijndaelDecryptor;
        // Replace me with a 16-byte key, share between Java and C#
        private static byte[] rawSecretKey = {Ox73, Ox65, Ox63, Ox72, Ox65, Ox74, Ox6B, Ox65, Ox79};

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

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

        private string Decrypt(byte[] encryptedData)
        {
            byte[] newClearData;

            try
            {
                newClearData = rijndaelDecryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
            }
            catch
            {
                throw;
            }
            return Encoding.ASCII.GetString(newClearData);
        }

        internal string DecyptString(string token)
        {
            //UTF8Encoding utf8 = new UTF8Encoding();
            return Decrypt(ASCIIEncoding.ASCII.GetBytes(token));
        }

        internal 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);
        }


        //Encryption Code
        public string EncryptAsBase64(string strData)
        {
            byte[] clearData = Encoding.ASCII.GetBytes(strData);
            byte[] encryptedData = Encrypt(clearData);
            return Convert.ToBase64String(encryptedData);
        }

        public byte[] Encrypt(byte[] clearData)
        {
            byte[] test1 = new byte[clearData.Length];
            try
            {               
                test1 = rijndaelDecryptor.TransformFinalBlock(clearData, 0, clearData.Length);               
            }
            catch
            {
                throw;
            }

            return test1;
        }
    }
}

有什么想法吗?提前非常感谢您!

【问题讨论】:

  • 我不明白你为什么要在 stackoverflow 链接中注入一个空格。您是要引用该问题还是将其用作示例 URL?我错过了什么?
  • 因为我是新人,我不能发布超过 1 个超链接,所以仍然包含它我不得不破解它
  • 堆栈溢出过去对我有很大帮助,这是我的第一篇文章,但我不知道如何在不发布大量代码的情况下仍然显示我需要的所有内容。如果我似乎超越了任何规则,我深表歉意。当我第一次发布时,它因为超链接而阻止了我,但他们给出的原因是为了减少垃圾邮件。

标签: c# java iphone android objective-c


【解决方案1】:

您可以在此处获取 NSData 类别来处理 Base64 编码/解码:

http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html

您可以在这里找到一个库和 NSData 类别来进行 AES 加密:

http://iphonedevelopment.blogspot.com/2009/02/strong-encryption-for-cocoa-cocoa-touch.html

在两者之间,您可以复制您正在做的事情,并且可能使用更少的代码......

【讨论】:

  • 抱歉耽搁了.. base 64 运行良好,但我仍然遇到加密问题.. 换句话说,我使用 CCCryptorStatus 结果 = CCCrypt( kCCEncrypt, //encrypt kCCAlgorithmAES128, //使用 AES 算法 kCCOptionPKCS7Padding,// 添加填充 (const void *)[aSymmetricKey bytes], //md5 加密字节密钥 kCCKeySizeAES256,// md5 密钥的长度 iv, //初始化向量 [self bytes], // data in [self length], //data in [self mutableBytes] length, //data out [self length], // data out 长度 &numBytesEncrypted );
  • 抱歉,之前没有在服务器端使用过,不知道会发生什么......我只是想验证服务器上的二进制文件与客户端上的二进制文件是否相同。另外,也许这是一个字节顺序问题?
  • 再次感谢您的回答。我最终只是重写了我的 .net 代码来匹配这个例子:dotmac.rationalmind.net/2009/02/…
  • 很高兴知道,感谢您的跟进。如果我必须加密某些东西以发送服务器端,我会记住这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 2014-08-16
相关资源
最近更新 更多