- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遇到了与文件解密相关的特定问题。我在 Java 中找到了一个程序,可以解密特定文件(这是游戏中的游戏保存文件,您可以在此处找到该文件的示例: https://www.adrive.com/public/6DBShx/game.sii ),我想将此程序重写为 C# - 这样我就可以将其完全集成我用 C# 编写的不同程序。这是我第一次使用加密文件,所以我编写的程序无法运行,实际上我不知道如何调试它。我编写的程序具有固定的文件路径 - 这是临时解决方案。
原始Java程序:
package scsc;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.Map;
import java.util.zip.InflaterInputStream;
/*
* Published under the Do What the Fuck You Want to Public License ( http://www.wtfpl.net/ )
*/
public class ScsC {
private static byte[] AES_KEY = new byte[]{
(byte) 0x2a, (byte) 0x5f, (byte) 0xcb, (byte) 0x17,
(byte) 0x91, (byte) 0xd2, (byte) 0x2f, (byte) 0xb6,
(byte) 0x02, (byte) 0x45, (byte) 0xb3, (byte) 0xd8,
(byte) 0x36, (byte) 0x9e, (byte) 0xd0, (byte) 0xb2,
(byte) 0xc2, (byte) 0x73, (byte) 0x71, (byte) 0x56,
(byte) 0x3f, (byte) 0xbf, (byte) 0x1f, (byte) 0x3c,
(byte) 0x9e, (byte) 0xdf, (byte) 0x6b, (byte) 0x11,
(byte) 0x82, (byte) 0x5a, (byte) 0x5d, (byte) 0x0a,
};
public static void main(String[] args) throws Exception {
if (args.length < 1) {
System.out.println("ERROR: expecting at least one file.");
} else {
removeCryptographyRestrictions();
for (String filename : args) {
decrypt(filename);
}
}
}
private static void decrypt(String filename) throws Exception {
File scsc = new File(filename);
if (!scsc.isFile() || !scsc.canWrite()) {
throw new IllegalArgumentException(filename + " is not a writable file.");
}
boolean encrypted = isEncrypted(scsc);
if (!encrypted) {
System.out.println(scsc + " does not seem to be encrypted.");
} else {
File decrypted = decrypt(scsc);
Files.copy(decrypted.toPath(), scsc.toPath(), StandardCopyOption.REPLACE_EXISTING);
System.out.println("decrypted: " + scsc);
}
}
private static boolean isEncrypted(File file) throws Exception {
byte[] header = new byte[4];
FileInputStream fis = new FileInputStream(file);
if (fis.read(header) != header.length) {
throw new RuntimeException("could not read header of " + file);
}
fis.close();
String headerAsString = new String(header, Charset.forName("UTF-8"));
return "ScsC".equals(headerAsString);
}
private static File decrypt(File input) throws Exception {
File out = File.createTempFile("scsc-", ".tmp");
out.deleteOnExit();
byte[] data = new byte[(int) (input.length())];
FileInputStream fis = new FileInputStream(input);
if (fis.read(data) != data.length) {
throw new RuntimeException("Could not read " + input + " into memory");
}
fis.close();
byte[] cipherText = new byte[data.length - 0x38];
byte[] iv = new byte[0x10];
System.arraycopy(data, 0x38, cipherText, 0, cipherText.length);
System.arraycopy(data, 0x24, iv, 0, iv.length);
byte[] decrypted = decrypt(cipherText, AES_KEY, iv);
ByteArrayInputStream bis = new ByteArrayInputStream(decrypted);
InflaterInputStream iis = new InflaterInputStream(bis);
InputStreamReader ir = new InputStreamReader(iis);
BufferedReader br = new BufferedReader(ir);
FileOutputStream fos = new FileOutputStream(out);
OutputStreamWriter osw = new OutputStreamWriter(fos);
PrintWriter pw = new PrintWriter(osw);
for (String line = br.readLine(); line != null; line = br.readLine()) {
pw.println(line);
}
pw.close();
br.close();
return out;
}
private static byte[] decrypt(byte[] cipherText, byte[] keyBytes, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(cipherText);
}
private static void removeCryptographyRestrictions() throws Exception {
// taken from http://stackoverflow.com/questions/1179672/unlimited-strength-jce-policy-files
final Class<?> jceSecurity = Class.forName("javax.crypto.JceSecurity");
final Class<?> cryptoPermissions = Class.forName("javax.crypto.CryptoPermissions");
final Class<?> cryptoAllPermission = Class.forName("javax.crypto.CryptoAllPermission");
final Field isRestrictedField = jceSecurity.getDeclaredField("isRestricted");
isRestrictedField.setAccessible(true);
isRestrictedField.set(null, false);
final Field defaultPolicyField = jceSecurity.getDeclaredField("defaultPolicy");
defaultPolicyField.setAccessible(true);
final PermissionCollection defaultPolicy = (PermissionCollection) defaultPolicyField.get(null);
final Field perms = cryptoPermissions.getDeclaredField("perms");
perms.setAccessible(true);
((Map<?, ?>) perms.get(defaultPolicy)).clear();
final Field instance = cryptoAllPermission.getDeclaredField("INSTANCE");
instance.setAccessible(true);
defaultPolicy.add((Permission) instance.get(null));
}
}
我用 C# 编写的代码似乎可以工作,但输出不符合预期...预期结果应该是可读文件(链接:https://www.adrive.com/public/E3rsfv/game.sii_decrypted_by_java)
解密文件的前几行:
SiiNunit
{
economy : _nameless.0357.B5D0 {
bank: _nameless.0371.CD48
player: _nameless.0369.3070
companies: 811
companies[0]: company.volatile.trameri.esbjerg
companies[1]: company.volatile.bcp.turku
companies[2]: company.volatile.itcc.liege
companies[3]: company.volatile.tree_et.geneve
companies[4]: company.volatile.tree_et.arhus
companies[5]: company.volatile.itcc.jonkoping
companies[6]: company.volatile.kaarfor.poznan
companies[7]: company.volatile.fcp.milano
companies[8]: company.volatile.posped.swansea
companies[9]: company.volatile.tradeaux.lille
companies[10]: company.volatile.euroacres.osnabruck
由 C# 解密 - 我无法在此处放置许多链接:(
前几行:
xڬ�M�$������C��4fcm�o��#=- ��rLV������̪[���<�8�J��F����t��C������:�>������>Ƿ_��Ƿ ��m��~|�9�T����ߦ?�����*[�����X��} ���=����S�������9��Q����?�����~����|���?? O���������ӳx�Y<<����uz�PoAw����w���������������~sz�� ������z|��Wf��ٜ�O�6�/�;I�m���[-����}�������c��T��| ��D��K�8S�ۯ�q�x�~�y�8lN_���)7�������ux��xг���@}l�����15} x�������c��#Ul�>>���͛|�T����>�q�����py�! ����X�'�tW����!��ow�w��۸c�Ə��^κ �ŗ�{�I�P���7���9<| ��O�}�������6_�ؾ=��}�����{RVħ�9��?��i�|A�awz#;���w�Km� %�3a�"~ݜ��9y4�����r�6����ގ_�/ �1<ݍqL����w�����=�l~���H\�y4J������(gU(k��m�S�S���es8��3m Ű,�M��_��~��w� ��S- ��Y|z�KP�P�����:ֆ������G�q��v�&�QLp6��C}<? �G5�cY�����q��)���q�D�|ڪε�i�����XI��>Ӕ_:c�
��~�<�1��h���=���{8m��G�8X��ٞҚB�6�Oۅ�Jy<�>���� ����b�Mu�l�v�W[u
�]�V'�����帗�Cv��H�C��9 ����t�e��V�������^�Cy�߁oIñ���r�����R��H���C{�����ӏ�m ���
以及在 c# 中创建它的类:
public partial class Form1 : Form
{
string file_original;
byte[] file_orig_bytes;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
byte[] AES_KEY = new byte[]{
(byte) 0x2a, (byte) 0x5f, (byte) 0xcb, (byte) 0x17,
(byte) 0x91, (byte) 0xd2, (byte) 0x2f, (byte) 0xb6,
(byte) 0x02, (byte) 0x45, (byte) 0xb3, (byte) 0xd8,
(byte) 0x36, (byte) 0x9e, (byte) 0xd0, (byte) 0xb2,
(byte) 0xc2, (byte) 0x73, (byte) 0x71, (byte) 0x56,
(byte) 0x3f, (byte) 0xbf, (byte) 0x1f, (byte) 0x3c,
(byte) 0x9e, (byte) 0xdf, (byte) 0x6b, (byte) 0x11,
(byte) 0x82, (byte) 0x5a, (byte) 0x5d, (byte) 0x0a,
};
string path = "game.sii";
load_file_to_memory(path);
//decrypt_file(AES_KEY);
byte[] iv = new byte[0x10];
byte[] cipherText = new byte[file_orig_bytes.Length - 0x38];
Array.Copy(file_orig_bytes, 0x38, cipherText, 0, cipherText.Length);
Array.Copy(file_orig_bytes, 0x24, iv, 0, iv.Length);
string new_file = DecryptStringFromBytes_Aes(cipherText, AES_KEY, iv);
int a;
}
private void load_file_to_memory(string path)
{
file_original = File.ReadAllText(path);
file_orig_bytes = File.ReadAllBytes(path);
int i;
}
static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key
, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
对此有什么帮助吗?谢谢
最佳答案
这是我的版本,看起来效果很好。你最后一个代码的问题是原始java版本中的未加密内容是用“InflaterInputStream”类操作的,在c#中我在sharpziplib中找到了这个类。
public class Test2
{
static string file_original;
static byte[] file_orig_bytes;
static void Main(string[] args)
{
byte[] AES_KEY = new byte[]{
(byte) 0x2a, (byte) 0x5f, (byte) 0xcb, (byte) 0x17,
(byte) 0x91, (byte) 0xd2, (byte) 0x2f, (byte) 0xb6,
(byte) 0x02, (byte) 0x45, (byte) 0xb3, (byte) 0xd8,
(byte) 0x36, (byte) 0x9e, (byte) 0xd0, (byte) 0xb2,
(byte) 0xc2, (byte) 0x73, (byte) 0x71, (byte) 0x56,
(byte) 0x3f, (byte) 0xbf, (byte) 0x1f, (byte) 0x3c,
(byte) 0x9e, (byte) 0xdf, (byte) 0x6b, (byte) 0x11,
(byte) 0x82, (byte) 0x5a, (byte) 0x5d, (byte) 0x0a,
};
string path = @"C:\temp_10\game.sii";
load_file_to_memory(path);
//decrypt_file(AES_KEY);
byte[] iv = new byte[0x10];
byte[] cipherText = new byte[file_orig_bytes.Length - 0x38];
Array.Copy(file_orig_bytes, 0x38, cipherText, 0, cipherText.Length);
Array.Copy(file_orig_bytes, 0x24, iv, 0, iv.Length);
byte[] decoded_binary_content = AESDecrypt(cipherText, AES_KEY, iv);
string decoded_string_content = "";
using (MemoryStream ms = new MemoryStream(decoded_binary_content))
using (ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream iis = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(ms))
using (StreamReader sr = new StreamReader(iis))
decoded_string_content = sr.ReadToEnd();
}
private static void load_file_to_memory(string path)
{
file_original = File.ReadAllText(path);
file_orig_bytes = File.ReadAllBytes(path);
}
//http://lamahashim.blogspot.it/2009/08/encyptiondecryption-in-c-and-java.html
static byte[] AESDecrypt(byte[] encryptedData, byte[] keyBytes, byte[] iv)
{
RijndaelManaged rijndaelCipher = new RijndaelManaged();
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.None;
rijndaelCipher.IV = iv;
rijndaelCipher.KeySize = 0x80;
rijndaelCipher.BlockSize = 0x80;
rijndaelCipher.Key = keyBytes;
rijndaelCipher.IV = iv;
byte[] plainText = rijndaelCipher.CreateDecryptor().TransformFinalBlock(encryptedData, 0, encryptedData.Length);
return plainText;
}
}
我已经从代码中显示的网址复制了解密函数
关于java - 将 AES 文件解密程序从 Java 重写为 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35070533/
我是 C 语言新手,我编写了这个 C 程序,让用户输入一年中的某一天,作为返回,程序将输出月份以及该月的哪一天。该程序运行良好,但我现在想简化该程序。我知道我需要一个循环,但我不知道如何去做。这是程序
我一直在努力找出我的代码有什么问题。这个想法是创建一个小的画图程序,并有红色、绿色、蓝色和清除按钮。我有我能想到的一切让它工作,但无法弄清楚代码有什么问题。程序打开,然后立即关闭。 import ja
我想安装screen,但是接下来我应该做什么? $ brew search screen imgur-screenshot screen
我有一个在服务器端工作的 UDP 套接字应用程序。为了测试服务器端,我编写了一个简单的 python 客户端程序,它发送消息“hello world how are you”。服务器随后应接收消息,将
我有一个 shell 脚本,它运行一个 Python 程序来预处理一些数据,然后运行一个 R 程序来执行一些长时间运行的任务。我正在学习使用 Docker 并且我一直在运行 FROM r-base:l
在 Linux 中。我有一个 c 程序,它读取一个 2048 字节的文本文件作为输入。我想从 Python 脚本启动 c 程序。我希望 Python 脚本将文本字符串作为参数传递给 c 程序,而不是将
对于一个类,我被要求编写一个 VHDL 程序,该程序接受两个整数输入 A 和 B,并用 A+B 替换 A,用 A-B 替换 B。我编写了以下程序和测试平台。它完成了实现和行为语法检查,但它不会模拟。尽
module Algorithm where import System.Random import Data.Maybe import Data.List type Atom = String ty
我想找到两个以上数字的最小公倍数 求给定N个数的最小公倍数的C++程序 最佳答案 int lcm(int a, int b) { return (a/gcd(a,b))*b; } 对于gcd,请查看
这个程序有错误。谁能解决这个问题? Error is :TempRecord already defines a member called 'this' with the same paramete
当我运行下面的程序时,我在 str1 和 str2 中得到了垃圾值。所以 #include #include #include using namespace std; int main() {
这是我的作业: 一对刚出生的兔子(一公一母)被放在田里。兔子在一个月大时可以交配,因此在第二个月的月底,每对兔子都会生出两对新兔子,然后死去。 注:在第0个月,有0对兔子。第 1 个月,有 1 对兔子
我编写了一个程序,通过对字母使用 switch 命令将十进制字符串转换为十六进制,但是如果我使用 char,该程序无法正常工作!没有 switch 我无法处理 9 以上的数字。我希望你能理解我,因为我
我是 C++ 新手(虽然我有一些 C 语言经验)和 MySQL,我正在尝试制作一个从 MySQL 读取数据库的程序,我一直在关注这个 tutorial但当我尝试“构建”解决方案时出现错误。 (我正在使
仍然是一个初学者,只是尝试使用 swift 中的一些基本函数。 有人能告诉我这段代码有什么问题吗? import UIKit var guessInt: Int var randomNum = arc
我正在用 C++11 编写一个函数,它采用 constant1 + constant2 形式的表达式并将它们折叠起来。 constant1 和 constant2 存储在 std::string 中,
我用 C++ 编写了这段代码,使用运算符重载对 2 个矩阵进行加法和乘法运算。当我执行代码时,它会在第 57 行和第 59 行产生错误,非法结构操作(两行都出现相同的错误)。请解释我的错误。提前致谢:
我是 C++ 的初学者,我想编写一个简单的程序来交换字符串中的两个字符。 例如;我们输入这个字符串:“EXAMPLE”,我们给它交换这两个字符:“E”和“A”,输出应该类似于“AXEMPLA”。 我在
我需要以下代码的帮助: 声明 3 个 double 类型变量,每个代表三角形的三个边中的一个。 提示用户为第一面输入一个值,然后 将用户的输入设置为您创建的代表三角形第一条边的变量。 将最后 2 个步
我是新来的,如果问题不好请见谅 任务:将给定矩阵旋转180度 输入: 1 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 输出: 16 15 14 13 12 11
我是一名优秀的程序员,十分优秀!