当前位置:首页 » 密码管理 » ios加密解密

ios加密解密

发布时间: 2022-05-02 23:21:44

‘壹’ ios应用开发过程中如何加密、防内购破解等,简单加密方法

在大多数iOS应用在开发者看来,封闭的iOS系统很安全,iOS应用也很安全,但事实上,iOS应用没有我们想象中的安全。如同安卓应用,iOS应用也面临着被破解的威胁,存在大量盗版情况,所以开发者对此一定要重视起来,应用在上市场之前还是要多做些相关的防护,例如:
1.本地数据加密
对NSUserDefaults,sqlite存储文件数据加密,保护帐号和关键信息。
2. URL编码加密
对程序中出现的URL进行编码加密,防止URL被静态分析
3. 网络传输数据加密
对客户端传输数据提供加密方案,有效防止通过网络接口的拦截获取
4. 方法体,方法名高级混淆
对应用程序的方法名和方法体进行混淆,保证源码被逆向后无法解析代码
5. 程序结构混排加密
对应用程序逻辑结构进行打乱混排,保证源码可读性降到最低

‘贰’ 关于iOS aes256加密的问题,请各位帮忙,搞了一个星期,急求答案!

之前在项目上用到AES256加密解密算法,刚开始在java端加密解密都没有问题,在iOS端加密解密也没有问题。但是奇怪的是在java端加密后的文件在iOS端无法正确解密打开,然后简单测试了一下,发现在java端和iOS端采用相同明文,相同密钥加密后的密文不一样!上网查了资料后发现iOS中AES加密算法采用的填充是PKCS7Padding,而java不支持PKCS7Padding,只支持PKCS5Padding。我们知道加密算法由算法+模式+填充组成,所以这两者不同的填充算法导致相同明文相同密钥加密后出现密文不一致的情况。那么我们需要在java中用PKCS7Padding来填充,这样就可以和iOS端填充算法一致了。
要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现,下面我会提供该包的下载。啰嗦了一大堆,下面是一个简单的测试,上代码!
001 package com.encrypt.file;
002
003
004 import java.io.UnsupportedEncodingException;
005 importjava.security.Key;
006 import java.security.Security;
007
008 importjavax.crypto.Cipher;
009 importjavax.crypto.SecretKey;
010 importjavax.crypto.spec.SecretKeySpec;
011
012 public classAES256Encryption{
013
014 /**
015 * 密钥算法
016 * java6支持56位密钥,bouncycastle支持64位
017 * */
018 public static finalString KEY_ALGORITHM="AES";
019
020 /**
021 * 加密/解密算法/工作模式/填充方式
022 *
023 * JAVA6 支持PKCS5PADDING填充方式
024 * Bouncy castle支持PKCS7Padding填充方式
025 * */
026 public static finalString CIPHER_ALGORITHM="AES/ECB/PKCS7Padding";
027
028 /**
029 *
030 * 生成密钥,java6只支持56位密钥,bouncycastle支持64位密钥
031 * @return byte[] 二进制密钥
032 * */
033 public static byte[] initkey() throwsException{
034
035 // //实例化密钥生成器
036 // Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
037 // KeyGenerator kg=KeyGenerator.getInstance(KEY_ALGORITHM, "BC");
038 // //初始化密钥生成器,AES要求密钥长度为128位、192位、256位
039 //// kg.init(256);
040 // kg.init(128);
041 // //生成密钥
042 // SecretKey secretKey=kg.generateKey();
043 // //获取二进制密钥编码形式
044 // return secretKey.getEncoded();
045 //为了便于测试,这里我把key写死了,如果大家需要自动生成,可用上面注释掉的代码
046 return new byte[] { 0x08, 0x08, 0x04, 0x0b, 0x02, 0x0f, 0x0b, 0x0c,
047 0x01, 0x03, 0x09, 0x07, 0x0c, 0x03, 0x07, 0x0a, 0x04, 0x0f,
048 0x06, 0x0f, 0x0e, 0x09, 0x05, 0x01, 0x0a, 0x0a, 0x01, 0x09,
049 0x06, 0x07, 0x09, 0x0d };
050 }
051
052 /**
053 * 转换密钥
054 * @param key 二进制密钥
055 * @return Key 密钥
056 * */
057 public static Key toKey(byte[] key) throwsException{
058 //实例化DES密钥
059 //生成密钥
060 SecretKey secretKey=newSecretKeySpec(key,KEY_ALGORITHM);
061 returnsecretKey;
062 }
063
064 /**
065 * 加密数据
066 * @param data 待加密数据
067 * @param key 密钥
068 * @return byte[] 加密后的数据
069 * */
070 public static byte[] encrypt(byte[] data,byte[] key) throwsException{
071 //还原密钥
072 Key k=toKey(key);
073 /**
074 * 实例化
075 * 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现
076 * Cipher.getInstance(CIPHER_ALGORITHM,"BC")
077 */
078 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
079 Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC");
080 //初始化,设置为加密模式
081 cipher.init(Cipher.ENCRYPT_MODE, k);
082 //执行操作
083 returncipher.doFinal(data);
084 }
085 /**
086 * 解密数据
087 * @param data 待解密数据
088 * @param key 密钥
089 * @return byte[] 解密后的数据
090 * */
091 public static byte[] decrypt(byte[] data,byte[] key) throwsException{
092 //欢迎密钥
093 Key k =toKey(key);
094 /**
095 * 实例化
096 * 使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现
097 * Cipher.getInstance(CIPHER_ALGORITHM,"BC")
098 */
099 Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);
100 //初始化,设置为解密模式
101 cipher.init(Cipher.DECRYPT_MODE, k);
102 //执行操作
103 returncipher.doFinal(data);
104 }
105 /**
106 * @param args
107 * @throws UnsupportedEncodingException
108 * @throws Exception
109 */
110 public static void main(String[] args) {
111
112 String str="AES";
113 System.out.println("原文:"+str);
114
115 //初始化密钥
116 byte[] key;
117 try {
118 key = AES256Encryption.initkey();
119 System.out.print("密钥:");
120 for(int i = 0;i<key.length;i++){
121 System.out.printf("%x", key[i]);
122 }
123 System.out.print("\n");
124 //加密数据
125 byte[] data=AES256Encryption.encrypt(str.getBytes(), key);
126 System.out.print("加密后:");
127 for(int i = 0;i<data.length;i++){
128 System.out.printf("%x", data[i]);
129 }
130 System.out.print("\n");
131
132 //解密数据
133 data=AES256Encryption.decrypt(data, key);
134 System.out.println("解密后:"+newString(data));
135 } catch (Exception e) {
136 // TODO Auto-generated catch block
137 e.printStackTrace();
138 }
139
140 }
141 }
运行程序后的结果截图:

ViewController.m文件

01 //
02 // ViewController.m
03 // AES256EncryptionDemo
04 //
05 // Created by 孙 裔 on 12-12-13.
06 // Copyright (c) 2012年 rich sun. All rights reserved.
07 //
08
09 #import "ViewController.h"
10 #import "EncryptAndDecrypt.h"
11
12 @interface ViewController ()
13
14 @end
15
16 @implementation ViewController
17 @synthesize plainTextField;
18 - (void)viewDidLoad
19 {
20 [super viewDidLoad];
21 // Do any additional setup after loading the view, typically from a nib.
22 }
23
24 - (void)didReceiveMemoryWarning
25 {
26 [super didReceiveMemoryWarning];
27 // Dispose of any resources that can be recreated.
28 }
29 //这个函数实现了用户输入完后点击视图背景,关闭键盘
30 - (IBAction)backgroundTap:(id)sender{
31 [plainTextField resignFirstResponder];
32 }
33
34 - (IBAction)encrypt:(id)sender {
35
36 NSString *plainText = plainTextField.text;//明文
37 NSData *plainTextData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
38
39 //为了测试,这里先把密钥写死
40 Byte keyByte[] = {0x08,0x08,0x04,0x0b,0x02,0x0f,0x0b,0x0c,0x01,0x03,0x09,0x07,0x0c,0x03,
41 0x07,0x0a,0x04,0x0f,0x06,0x0f,0x0e,0x09,0x05,0x01,0x0a,0x0a,0x01,0x09,
42 0x06,0x07,0x09,0x0d};
43 //byte转换为NSData类型,以便下边加密方法的调用
44 NSData *keyData = [[NSData alloc] initWithBytes:keyByte length:32];
45 //
46 NSData *cipherTextData = [plainTextData AES256EncryptWithKey:keyData];
47 Byte *plainTextByte = (Byte *)[cipherTextData bytes];
48 for(int i=0;i<[cipherTextData length];i++){
49 printf("%x",plainTextByte[i]);
50 }
51
52 }
53 @end

附上出处链接:http://blog.csdn.net/pjk1129/article/details/8489550

‘叁’ ios 中开发中用户信息中的加密方式有哪些

5.1 通过简单的URLENCODE + BASE64编码防止数据明文传输
5.2 对普通请求、返回数据,生成MD5校验(MD5中加入动态密钥),进行数据完整性(简单防篡改,安全性较低,优点:快速)校验。
5.3 对于重要数据,使用RSA进行数字签名,起到防篡改作用。
5.4 对于比较敏感的数据,如用户信息(登陆、注册等),客户端发送使用RSA加密,服务器返回使用DES(AES)加密。
原因:客户端发送之所以使用RSA加密,是因为RSA解密需要知道服务器私钥,而服务器私钥一般盗取难度较大;如果使用DES的话,可以通过破解客户端获取密钥,安全性较低。而服务器返回之所以使用DES,是因为不管使用DES还是RSA,密钥(或私钥)都存储在客户端,都存在被破解的风险,因此,需要采用动态密钥,而RSA的密钥生成比较复杂,不太适合动态密钥,并且RSA速度相对较慢,所以选用DES)
把相关算法的代码也贴一下吧 (其实使用一些成熟的第三方库或许会来得更加简单,不过自己写,自由点)。注,这里的大部分加密算法都是参考一些现有成熟的算法,或者直接拿来用的。
1、MD5
//因为是使用category,所以木有参数传入啦

-(NSString *) stringFromMD5 {
if(self == nil || [self length] == 0) {
return nil;
}
const char *value = [self UTF8String];
unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(value, strlen(value), outputBuffer);
NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
[outputString appendFormat:@"%02x",outputBuffer[count]];
}
return [outputString autorelease];
}

2、Base64

+ (NSString *) base64EncodeData: (NSData *) objData {
const unsigned char * objRawData = [objData bytes];
char * objPointer;
char * strResult;

// Get the Raw Data length and ensure we actually have data
int intLength = [objData length];
if (intLength == 0) return nil;

// Setup the String-based Result placeholder and pointer within that placeholder
strResult = (char *)calloc(((intLength + 2) / 3) * 4, sizeof(char));
objPointer = strResult;

// Iterate through everything
while (intLength > 2) { // keep going until we have less than 24 bits
*objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
*objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
*objPointer++ = _base64EncodingTable[((objRawData[1] & 0x0f) << 2) + (objRawData[2] >> 6)];
*objPointer++ = _base64EncodingTable[objRawData[2] & 0x3f];

// we just handled 3 octets (24 bits) of data
objRawData += 3;
intLength -= 3;
}

// now deal with the tail end of things
if (intLength != 0) {
*objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
if (intLength > 1) {
*objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
*objPointer++ = _base64EncodingTable[(objRawData[1] & 0x0f) << 2];
*objPointer++ = '=';
} else {
*objPointer++ = _base64EncodingTable[(objRawData[0] & 0x03) << 4];
*objPointer++ = '=';
*objPointer++ = '=';
}
}

// Terminate the string-based result
*objPointer = '\0';

NSString *rstStr = [NSString stringWithCString:strResult encoding:NSASCIIStringEncoding];
free(objPointer);
return rstStr;
}

3、AES
-(NSData*) EncryptAES: (NSString *) key {
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));

[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [self length];

size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);

size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}

free(buffer);
return nil;
}

4、RSA

- (NSData *) encryptWithData:(NSData *)content {
size_t plainLen = [content length];
if (plainLen > maxPlainLen) {
NSLog(@"content(%ld) is too long, must < %ld", plainLen, maxPlainLen);
return nil;
}

void *plain = malloc(plainLen);
[content getBytes:plain
length:plainLen];

size_t cipherLen = 128; // currently RSA key length is set to 128 bytes
void *cipher = malloc(cipherLen);

OSStatus returnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plain,
plainLen, cipher, &cipherLen);

NSData *result = nil;
if (returnCode != 0) {
NSLog(@"SecKeyEncrypt fail. Error Code: %ld", returnCode);
}
else {
result = [NSData dataWithBytes:cipher
length:cipherLen];
}

free(plain);
free(cipher);

return result;
}

‘肆’ ios 公钥字符串怎么加密解密

最近几天折腾了一下如何在iOS上使用RSA来加密。iOS上并没有直接的RSA加密API。但是iOS提供了x509的API,而x509是支持RSA加密的。因此,我们可以通过制作自签名的x509证书(由于对安全性要求不高,我们并不需要使用CA认证的证书),再调用x509的相关API来进行加密。接下来记录一下整个流程。

第一步,制作自签名的证书

  1. 最简单快捷的方法,打开Terminal,使用openssl(Mac OS X自带)生成私钥和自签名的x509证书。

  2. openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650

  3. 按照命令行的提示输入内容就行了。

  4. 几个说明:

  5. public_key.der是输出的自签名的x509证书,即我们要用的。

  6. private_key.pem是输出的私钥,用来解密的,请妥善保管。

  7. rsa:1024这里的1024是密钥长度,1024是比较安全的,如果需要更安全的话,可以用2048,但是加解密代价也会增加。

  8. -days:证书过期时间,一定要加上这个参数,默认的证书过期时间是30天,一般我们不希望证书这么短就过期,所以写上比较合适的天数,例如这里的3650(10年)。

  9. 事实上,这一行命令包含了好几个步骤(我研究下面这些步骤的原因是我手头已经由一个private_key.pem私钥了,想直接用这个来生成x509证书,也就是用到了下面的2-3)

  10. 1)创建私钥

  11. openssl genrsa -out private_key.pem 1024

  12. 2)创建证书请求(按照提示输入信息)

  13. openssl req -new -out cert.csr -key private_key.pem

  14. 3)自签署根证书

  15. openssl x509 -req -in cert.csr -out public_key.der -outform der -signkey private_key.pem -days 3650

  16. 2.验证证书。把public_key.der拖到xcode中,如果文件没有问题的话,那么就可以直接在xcode中打开,看到证书的各种信息。

第二步,使用public_key.der来进行加密。

  1. 导入Security.framework。

  2. 2.把public_key.der放到mainBundle中(一般直接拖到Xcode就行啦)。

  3. 3.从public_key.der读取公钥。

  4. 4.加密。

  5. 下面是参考代码(只能用于加密长度小于等于116字节的内容,适合于对密码进行加密。使用了ARC,不过还是要注意部分资源需要使用CFRealse来释放)

  6. RSA.h

  7. //

  8. // RSA.h

  9. //

  10. #import <Foundation/Foundation.h>

@interface RSA : NSObject {

SecKeyRef publicKey;

SecCertificateRef certificate;

SecPolicyRef policy;

SecTrustRef trust;

size_t maxPlainLen;

}


- (NSData *) encryptWithData:(NSData *)content;

- (NSData *) encryptWithString:(NSString *)content;


@end


RSA.m

//

// RSA.m

//

#import "RSA.h"


@implementation RSA


- (id)init {

self = [super init];

NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key"

ofType:@"der"];

if (publicKeyPath == nil) {

NSLog(@"Can not find pub.der");

return nil;

}

NSDate *publicKeyFileContent = [NSData dataWithContentsOfFile:publicKeyPath];

if (publicKeyFileContent == nil) {

NSLog(@"Can not read from pub.der");

return nil;

}

certificate = SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef)publicKeyFileContent);

if (certificate == nil) {

NSLog(@"Can not read certificate from pub.der");

return nil;

}

policy = SecPolicyCreateBasicX509();

OSStatus returnCode = (certificate, policy, trust);

if (returnCode != 0) {

NSLog(@" fail. Error Code: %ld", returnCode);

return nil;

}

SecTrustResultType trustResultType;

returnCode = SecTrustEvaluate(trust, trustResultType);

if (returnCode != 0) {

NSLog(@"SecTrustEvaluate fail. Error Code: %ld", returnCode);

return nil;

}

publicKey = SecTrustCopyPublicKey(trust);

if (publicKey == nil) {

NSLog(@"SecTrustCopyPublicKey fail");

return nil;

}

maxPlainLen = SecKeyGetBlockSize(publicKey) - 12;

return self;

}


- (NSData *) encryptWithData:(NSData *)content {

size_t plainLen = [content length];

if (plainLen > maxPlainLen) {

NSLog(@"content(%ld) is too long, must < %ld", plainLen, maxPlainLen);

return nil;

}

void *plain = malloc(plainLen);

[content getBytes:plain

length:plainLen];

size_t cipherLen = 128; // 当前RSA的密钥长度是128字节

void *cipher = malloc(cipherLen);

OSStatus returnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plain,

plainLen, cipher, cipherLen);

NSData *result = nil;

if (returnCode != 0) {

NSLog(@"SecKeyEncrypt fail. Error Code: %ld", returnCode);

}

else {

result = [NSData dataWithBytes:cipher

length:cipherLen];

}

free(plain);

free(cipher);

return result;

}


- (NSData *) encryptWithString:(NSString *)content {

return [self encryptWithData:[content dataUsingEncoding:NSUTF8StringEncoding]];

}


- (void)dealloc{

CFRelease(certificate);

CFRelease(trust);

CFRelease(policy);

CFRelease(publicKey);

}


@end


使用方法:

RSA *rsa = [[RSA alloc] init];

if (rsa != nil) {

NSLog(@"%@",[rsa encryptWithString:@"test"]);

}

else {

NSLog(@"init rsa error");

}

‘伍’ iOS代码加密的几种方式

众所周知的是大部分iOS代码一般不会做加密加固,因为iOS
APP一般是通过AppStore发布的,而且苹果的系统难以攻破,所以在iOS里做代码加固一般是一件出力不讨好的事情。万事皆有例外,不管iOS、adr还是js,加密的目的是为了代码的安全性,虽然现在开源畅行,但是不管个人开发者还是大厂皆有保护代码安全的需求,所以iOS代码加固有了生存的土壤。下面简单介绍下iOS代码加密的几种方式。

iOS代码加密的几种方式

1.字符串加密

字符串会暴露APP的很多关键信息,攻击者可以根据从界面获取的字符串,快速找到相关逻辑的处理函数,从而进行分析破解。加密字符串可以增加攻击者阅读代码的难度以及根据字符串静态搜索的难度。

一般的处理方式是对需要加密的字符串加密,并保存加密后的数据,再在使用字符串的地方插入解密算法。简单的加密算法可以把NSString转为byte或者NSData的方式,还可以把字符串放到后端来返回,尽量少的暴露页面信息。下面举个简单例子,把NSString转为16进制的字符串:

2.符号混淆

符号混淆的中心思想是将类名、方法名、变量名替换为无意义符号,提高应用安全性;防止敏感符号被class-mp工具提取,防止IDA Pro等工具反编译后分析业务代码。目前市面上的IOS应用基本上是没有使用类名方法名混淆的。

  • 别名

  • 在编写代码的时候直接用别名可能是最简单的一种方式,也是比较管用的一种方式。因为你的app被破解后,假如很容易就能从你的类名中寻找到蛛丝马迹,那离hook只是一步之遥,之前微信抢红包的插件应该就是用hook的方式执行的。

    b.C重写

    编写别名的方式不是很易读,而且也不利于后续维护,这时你可能需要升级一下你的保护方式,用C来重写你的代码吧。这样把函数名隐藏在结构体中,用函数指针成员的形式存储,编译后,只留下了地址,去掉了名字和参数表,让他们无从下手( from 念茜)。如下例子:

    c.脚本处理

    稍微高级一点的是脚本扫描处理替换代码,因为要用到linux命令来编写脚本,可能会有一点门槛,不过学了之后你就可以出去吹嘘你全栈工程师的名头啦。。。

    linux脚本比较常用的几个命令如下:

    脚本混淆替换是用上述几个命令扫描出来需要替换的字符串,比如方法名,类名,变量名,并做替换,如果你能熟练应用上述几个命令,恭喜你,已经了解了脚本的一点皮毛了。

    如以下脚本搜索遍历了代码目录下的需要混淆的关键字:

    替换的方式可以直接扫描文件并对文件中的所有内容替换,也可以采用define的方式定义别名。例如:

    d.开源项目ios-class-guard

    该项目是基于class-mp的扩展,和脚本处理类似,是用class-mp扫描出编译后的类名、方法名、属性名等并做替换,只是不支持隐式C方法的替换,有兴趣的同学可以使用下。

    3.代码逻辑混淆

    代码逻辑混淆有以下几个方面的含义:

    对方法体进行混淆,保证源码被逆向后该部分的代码有很大的迷惑性,因为有一些垃圾代码的存在;

    对应用程序逻辑结构进行打乱混排,保证源码可读性降到最低,这很容易把破解者带到沟里去;

    它拥有和原始的代码一样的功能,这是最最关键的。

    一般使用obfuscator-llvm来做代码逻辑混淆,或许会对该开源工具做个简单介绍。

    4.加固SDK

    adr中一般比较常见的加固等操作,iOS也有一些第三方提供这样的服务,但是没有真正使用过,不知道效果如何。

    当然还有一些第三方服务的加固产品,基本上都是采用了以上一种或几种混淆方式做的封装,如果想要直接可以拿来使用的服务,可以采用下,常用的一些服务如下:

    几维安全

    iOS加密可能市场很小,但是存在必有道理,在越狱/开源/极客的眼中,你的APP并没有你想象的那么安全,如果希望你的代码更加安全,就应给iOS代码加密。

‘陆’ iOS传过来的AES加密数据PHP怎么解密

使用PHP解密数据就可以了,代码参考

1、使用mcrypt扩展方式实现:http://www.oschina.net/code/snippet_248412_15378

加密解密代码中都有例子了


2、纯PHP实现:http://www.oschina.net/code/snippet_222150_15575

加密函数:AESEncryptCtr()

解密函数:AESDecryptCtr()

热点内容
漆昼之翁密码是多少 发布:2025-05-10 15:52:55 浏览:846
linux与windows的分区 发布:2025-05-10 15:40:18 浏览:996
搜狐视频破解缓存 发布:2025-05-10 15:39:06 浏览:807
存储器主要用来 发布:2025-05-10 15:17:34 浏览:427
两台服务器怎么部署redis 发布:2025-05-10 15:16:09 浏览:903
cocoa编程 发布:2025-05-10 15:15:18 浏览:181
中控导航什么配置好 发布:2025-05-10 15:15:07 浏览:790
个人网站的数据库 发布:2025-05-10 15:10:17 浏览:119
会编程好处 发布:2025-05-10 14:58:49 浏览:480
编程的过程 发布:2025-05-10 14:58:38 浏览:343