- 浏览: 523868 次
- 性别:
- 来自: 河北
最新评论
-
zrong:
已经支持了。
杂谈:倘若flash支持JPEG XR格式? -
蓝月儿:
anr是这么解释的呀。。。一次面试的笔试题,竟然都不知道是这样 ...
什么是ANR 如何避免它? -
hymer2011:
这是纯jsp的还是基于ssh的?
jsp网上商城源码 -
敲敲大葱头:
好文章,学习了
Android-SDK SearchableDemo--浮动搜索框(SearchManager) -
overkill:
你好,我在使用InstallAnywhere的silent安装 ...
InstallAnyWhere学习笔记 ( by quqi99 )
Java加密与解密(by quqi99)
作者:张华 发表于:2009-12-31
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明
1)base64算法
加密:new BASE64Encoder().encode(byte[] b)
解密: new BASE64Decoder().decode(byte[] b)
2) MD5或SHA摘要
MessageDigest digest = MessageDigest.getInstance("SHA"); //若是md5就 "MD5"
digest.update(byte[] b);
sha.degest();
3) 字节与16进制互换。
String strDigits = "0123456789ABCDEF";
String strDigitArr = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F");
public String byte2Hex(byte[] bytes){
String hs = "";
String stmp = "";
for(int =0;n<bytes.length;n++){
stmp = (Integer.toHexString(bytes[n] & 0XFF));
if(stmp.length() == 1)
hs = hs + "0" + stmp;
else
hs = hs + stmp;
}
return hs.toUpperCase();
}
public byte[] hex2Str(String hexStr){
char[] hexs = hexStr.toCharArray();
byte[] bytes = new byte[hexStr.length()/2];
int n;
for(int i=0;i<bytes.length;i++){
n = strDigits.indexOf(hexs[2*i]) * 16;
n += strDigits.indexOf(hexs[2*i + 1]);
bytes[i] = (byte)(n & 0xff);
}
}
4) RSA有公钥与密钥
生成密钥对:
private KeyPair generateKeyPair(){
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(1024,new SecureRandom());
KeyPari key = gen.genKeyPair();
return key;
}
//从公钥字节恢复公钥
//从密钥字节恢复密钥与这差不多,只不过将public字眼换成private
private RSAPublicKey recoverRSAPublicKey(byte[] modulus, byte[] publicExponent){
RSAPublicKeySpec spec = new RSAPublicKeySpec(new BigInteger(modulus),new BigInteger(publicExponent));
KeyFactory fac = KeyFacotry.getInstance("RSA");
RSAPublicKey key = (RSAPublicKey)fac.generatePublic(spec);
return key;
}
//RSA加解密
private byte[] rsaTrans(int mode,Key key,byte[] data){
if(mode != Cipher.ENCRYPT_MODE && mode!=Cipher.DECRYPT_MODE)
throw new Exception("");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(mode,key,new SecureRandom());
return cipher.doFinal(data);
}
使用上述的方法:
KeyPair keyPair = generateKeyPair();
RSAPublicKey pubKey = (RSAPublicKey)keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
byte[] pubModulusBytes = pubKey.getModulus().toByteArray();
byte[] publicExponentBytes = pubKey.getPublicExponent().toByteArray();
byte[] privateModulusBytes = privateKey.getModulus().toByteArray();
byte[]privateExponentBytes = privateKey.getPrivateExponent().toByteArray();
pubKey = recoverRSAPublicKey(pubModulusBytes,publicExponentBytes); //恢复公钥,恢复密钥类似
//用私钥加密
byte[] encryptData = rsaTran(Cipher.ENCRYPT_MODE,privateKey,bytes));
//用公钥解密
encryptData = rsaTran(Cipher.DECRYPT_MODE,privateKey,bytes));
5) DES为单钥加密机制,加密过程与RSA差不多。
步骤1:生成一个安全密匙。在加密或解密任何数据之前需要有一个密匙。密匙是随同被加密的应用一起发布的一小段数据
import java.security.SecureRandom;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class GenerateKey
{
static public void main( String args[] ) throws Exception {
String keyFilename = "key.data";
String algorithm = "DES";
// 生成密匙
SecureRandom sr = new SecureRandom();
KeyGenerator kg = KeyGenerator.getInstance( algorithm );
kg.init( sr );
SecretKey key = kg.generateKey();//[-68, -68, -57, -71, 42, -125, 32, 13]
// 把密匙数据保存到文件
Util.writeFile( keyFilename, key.getEncoded() );
}
}
步骤2:加密数据。得到密匙之后,接下来就可以用它加密数据。
// DES算法要求有一个可信任的随机数源
SecureRandom sr = new SecureRandom();
byte rawKeyData[] = /* 用某种方法获得密匙数据 */;
// 从原始密匙数据创建DESKeySpec对象
DESKeySpec dks = new DESKeySpec( rawKeyData );
// 创建一个密匙工厂,然后用它把DESKeySpec转换
// 一个SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance( "DES" );
SecretKey key = keyFactory.generateSecret( dks );
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance( "DES" );
// 用密匙初始化Cipher对象
cipher.init( Cipher.ENCRYPT_MODE, key, sr )
// 现在,获取数据并加密
byte data[] = /* 用某种方法获取数据 */
// 正式执行加密操作
byte encryptedData[] = cipher.doFinal( data );
// 进一步处理加密后的数据
步骤3:解密数据。
在上述加密数据将
cipher.init( Cipher.ENCRYPT_MODE, key, sr );
一句换成
cipher.init( Cipher.DECRYPT_MODE, key, sr );
doSomething( encryptedData );
下面附一个练习的例子,写的一个License,代码如下:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
/**
* @version 0.10 2010-2-28
* @author Zhang Hua
* 利用license机制来保护Java软件产品的安全
*/
public class License {
private static final String licensePath = "license.dat";
private static final String keyFilename = "key.data";
private static SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd"); //yyyy-MM-dd HH:mm:ss
//Product.title , AppServer
private String title = "AppServer";
//Product.sku, J2EE/CORBA
private String sku = "J2EE/CORBA";
//Serial.number, MAC Address
private byte[] serialNumber;
//Platform, all
private String platform = "";
//Trial.license
private boolean isTrial;
//License.expiry, 2010-05-12
private String expiry = "";
//Test
public static void main(String[] args){
//为用户生成license,并email给他
License om = new License();
om.setTitle("AppServer");
om.setSku("J2EE/CORBA");
String mac = getMACAddress();
om.setPlatform("Windows");
om.setTrial(false);
om.setExpiry("2010-05-12");
License.generateLicense(om,mac);
//在程序中校验license
License.validate();
}
//为用户生成license, 也就是将serialNumber字段的MAC加密
public static License generateLicense(License om,String mac){
try{
//密匙不存在,则生成密匙
if(! new File(keyFilename).exists()){
generateKey();
}
//用密匙加密数据
byte rawKeyData[] = readFile(keyFilename); //用某种方法获得密匙数据
DESKeySpec dks = new DESKeySpec( rawKeyData ); //从原始密匙数据创建DESKeySpec对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); //创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
SecretKey key = keyFactory.generateSecret( dks );
Cipher cipher = Cipher.getInstance( "DES" ); //Cipher对象实际完成加密操作
SecureRandom sr = new SecureRandom(); //DES算法要求有一个可信任的随机数源
cipher.init(Cipher.ENCRYPT_MODE, key, sr ); //用密匙初始化Cipher对象
byte data[] = mac.getBytes(); //用某种方法获取数据
byte encryptedData[] = cipher.doFinal( data ); //正式执行加密操作
System.out.println("加密后的数据:" + encryptedData);
om.setSerialNumber(encryptedData);
//输出license
write(om);
}catch(Exception e){
e.printStackTrace();
}
return om;
}
//生成密匙
private static boolean generateKey(){
boolean result = false'
String algorithm = "DES";
try{
SecureRandom sr = new SecureRandom(); //DES算法要求有一个可信任的随机数源
KeyGenerator kg = KeyGenerator.getInstance(algorithm);
kg.init( sr );
SecretKey key = kg.generateKey(); //[-68, -68, -57, -71, 42, -125, 32, 13]
result = writeFile(keyFilename, key.getEncoded()); //把密匙数据保存到文件
}catch(Exception e){
e.printStackTrace();
}
return result;
}
public static boolean validate(){
boolean result = false;
try{
License om = read()'
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith(om.getPlatform().toLowerCase()) || "all".equals(om.getPlatform())) {
Date expireDate = sdf.parse(om.getExpiry());
if(expireDate.getTime() - new Date().getTime() < 0){
System.err.println("License过期了");
result = false'
}else{
if(om.isTrial()){
System.out.println("试用License有效");
result = true;
}else{
String mac = getMACAddress();
//用密匙解密数据
byte rawKeyData[] = readFile(keyFilename); //用某种方法获得密匙数据
DESKeySpec dks = new DESKeySpec( rawKeyData ); //从原始密匙数据创建DESKeySpec对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); //创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
SecretKey key = keyFactory.generateSecret( dks );
Cipher cipher = Cipher.getInstance( "DES" ); //Cipher对象实际完成加密操作
SecureRandom sr = new SecureRandom(); //DES算法要求有一个可信任的随机数源
cipher.init(Cipher.DECRYPT_MODE, key, sr ); //用密匙初始化Cipher对象
byte data[] = om.getSerialNumber(); //用某种方法获取数据
byte encryptedData[] = cipher.doFinal(data); //正式执行加密操作
String tmp = new String(encryptedData);
System.out.println("解密后的数据:" + tmp);
if(mac.equals(tmp)){
System.out.println("License有效");
result = true;
}else{
System.err.println("License无效");
result = false;
}
}
}
}else{
System.err.println("License的平台无效");
result = false;
}
}catch(Exception e){
e.printStackTrace();
}
return result;
}
public static License read(){
License om = null;
try{
om = new License();
ObjectInputStream in = new ObjectInputStream(new FileInputStream(licensePath));
om.setTitle((String)in.readObject());
om.setSku((String)in.readObject());
om.setPlatform((String)in.readObject());
om.setTrial(in.readBoolean());
om.setExpiry((String)in.readObject());
om.setSerialNumber((byte[])in.readObject());
in.close();
}catch(Exception e){
e.printStackTrace();
}
return om;
}
public static boolean write(License om){
boolean result;
try{
File f = new File(licensePath);
if(f.exists())
f.delete();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(om.getTitle());
out.writeObject(om.getSku());
out.writeObject(om.getPlatform());
out.writeBoolean(om.isTrial());
out.writeObject(om.getExpiry());
out.writeObject(om.getSerialNumber());
out.close();
result = true;
}catch(Exception e){
e.printStackTrace();
result = false;
}
return result;
}
public static boolean writeFile(String path, byte[] bytes){
boolean result = false;
try {
FileOutputStream fos = new FileOutputStream(path);
fos.write(bytes);
fos.close();
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static byte[] readFile(String path){
byte[] bytes = null;
try {
FileInputStream fin = new FileInputStream(path);
bytes = new byte[fin.available()];
fin.read(bytes);
fin.close();
} catch (Exception e) {
e.printStackTrace();
}
return bytes;
}
public static String getMACAddress() {
String address = "";
String os = System.getProperty("os.name");
if (os.startsWith("Windows")) {
try {
String command = "cmd.exe /c ipconfig /all";
Process p = Runtime.getRuntime().exec(command);
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
if (line.indexOf("Physical Address") > 0) {
int index = line.indexOf(":");
index += 2;
address = line.substring(index);
break;
}
}
br.close();
return address.trim();
} catch (IOException e) {
e.printStackTrace();
}
} else if (os.startsWith("Linux")) {
String command = "/bin/sh -c ifconfig -a";
Process p;
try {
p = Runtime.getRuntime().exec(command);
BufferedReader br = new BufferedReader(new InputStreamReader(p
.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
if (line.indexOf("HWaddr") > 0) {
int index = line.indexOf("HWaddr") + "HWaddr".length();
address = line.substring(index);
break;
}
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
address = address.trim();
return address;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSku() {
return sku;
}
public void setSku(String sku) {
this.sku = sku;
}
public byte[] getSerialNumber() {
return serialNumber;
}
public void setSerialNumber(byte[] serialNumber) {
this.serialNumber = serialNumber;
}
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public boolean isTrial() {
return isTrial;
}
public void setTrial(boolean isTrial) {
this.isTrial = isTrial;
}
public String getExpiry() {
return expiry;
}
public void setExpiry(String expiry) {
this.expiry = expiry;
}
}
关于license的生成,还想说几点:
1)无论是生成二进制license,还是文件的,最好带上指纹校验。
2)无论是用什么加密算法无所谓,问题的关键不在里,在于JAVA容易被反编译,反编译之后很容易看到你的加密算法,人家可以
把这块替掉或者删除掉。另外,人家也可以在主程序调用license处的地方反编译之后直接返回true。
有网友说,对JAR包加密,然后自定义classloader解密,我看也是不行的,因为你自定义的classloader也是很容易被
反编译的,那样你的解密过程也就都清楚了。
所以,我认为,JAVA的东西就应用是开源的。当然,我们可以用混淆工具进行一定程度的混淆,算是给反编译增中一点困难的。
3)我试用了混淆工具proguard,觉得混淆工具有点不满足我的需求。
它默认是都混淆,但可以通过-keep参数指定某些类某些方法不混淆。
而我的需求是大多数类我不想混淆,我只想对少数几个类混淆,而且我的程序非常大,如果按照它的通过-keep参数指定
我不想混淆的类是不是有点太麻烦了。
下面是一个我测试过程中算是比较通用的配置my.conf,它对public,protected都不进行混淆,
用java -cp .;test.jar -jar proguard.jar @E:/workspace/test/my.conf 可执行混淆操作,my.conf文件如下:
-injars E:/workspace/test/test.jar
-outjars E:/workspace/test/test_out.jar
-libraryjars <java.home>/lib/rt.jar
-libraryjars E:/workspace/test/lib/mail.jar
-printmapping proguard.map
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keep public class org.**
-keep public class * {
public protected *;
}
-keepclassmembernames class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
一、密码学上常用的概念
/**
*MessageDigestExample.java
*Copyright 2005-2-16
*/
import java.security.MessageDigest;
/**
*单一的消息摘要算法,不使用密码.可以用 来对明文消息(如:密码)隐藏保存
*/
public class MessageDigestExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java MessageDigestExample text");
System.exit(1);
}
byte[] plainText=args[0].getBytes("UTF8");
//使用getInstance("算法")来获得消息摘要, 这里使用SHA-1的160位算法
MessageDigest messageDigest=MessageDigest.getInstance("SHA-1");
System.out.println(" "+messageDigest.getProvider().getInfo());
//开 始使用算法
messageDigest.update(plainText);
System.out.println(" Digest:");
//输出算法运算结果
System.out.println(new String(messageDigest.digest(),"UTF8"));
}
}
还可以通过消息认证码 来进行加密实现,javax.crypto.Mac提供了一个解决方案,有兴趣者可以参考相关API文档,本文只是简单介绍什么是摘要算法。
2)私钥加密:
这种最好理解,使用对称算法。比如:A用一个密钥对一个文件加密,而B读取这个文件的话,则需要和A一样的密 钥,双方共享一个私钥(而在web环境下,私钥在传递时容易被侦听):
使用私钥加密的话,首先需要一个密钥,可用 javax.crypto.KeyGenerator产生一个密钥(java.security.Key),然后传递给一个加密工具 (javax.crypto.Cipher),该工具再使用相应的算法来进行加密,主要对称算法有:DES(实际密钥只用到56位),AES(支持三种密 钥长度:128、192、256位),通常首先128位,其他的还有DESede等,jdk1.5种也提供了对对称算法的支持,以下例子使用AES算法来 加密:
/**
*PrivateExmaple.java
*Copyright 2005-2-16
*/
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
/**
*私鈅加密,保证消息机密性
*/
public class PrivateExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java PrivateExample ");
System.exit(1);
}
byte[] plainText=args[0].getBytes("UTF8");
//通过KeyGenerator形成一个key
System.out.println(" Start generate AES key");
KeyGenerator keyGen=KeyGenerator.getInstance("AES");
keyGen.init(128);
Key key=keyGen.generateKey();
System.out.println("Finish generating DES key");
//获得一个私鈅加密类Cipher,ECB是加密方式,PKCS5Padding是填充方法
Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
System.out.println(" "+cipher.getProvider().getInfo());
//使用私鈅加密
System.out.println(" Start encryption:");
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[] cipherText=cipher.doFinal(plainText);
System.out.println("Finish encryption:");
System.out.println(new String(cipherText,"UTF8"));
System.out.println(" Start decryption:");
cipher.init(Cipher.DECRYPT_MODE,key);
byte[] newPlainText=cipher.doFinal(cipherText);
System.out.println("Finish decryption:");
System.out.println(new String(newPlainText,"UTF8"));
}
}
3)公钥加密:
/**
*PublicExample.java
*Copyright 2005-2-16
*/
import java.security.Key;
import javax.crypto.Cipher;
import java.security.KeyPairGenerator ;
import java.security.KeyPair;
/**
*一个简单的公鈅加密例子,Cipher类使用KeyPairGenerator 生成的公鈅和私鈅
*/
public class PublicExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java PublicExample ");
System.exit(1);
}
byte[] plainText=args[0].getBytes("UTF8");
//构成一个RSA密钥
System.out.println(" Start generating RSA key");
KeyPairGenerator keyGen=KeyPairGenerator .getInstance("RSA");
keyGen.initialize(1024);
KeyPair key=keyGen.generateKeyPair();
System.out.println("Finish generating RSA key");
//获得一个RSA的Cipher类,使用公鈅加密
Cipher cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");
System.out.println(" "+cipher.getProvider().getInfo());
System.out.println(" Start encryption");
cipher.init(Cipher.ENCRYPT_MODE,key.getPublic());
byte[] cipherText=cipher.doFinal(plainText);
System.out.println("Finish encryption:");
System.out.println(new String(cipherText,"UTF8"));
//使用私鈅解密
System.out.println(" Start decryption");
cipher.init(Cipher.DECRYPT_MODE,key.getPrivate());
byte[] newPlainText=cipher.doFinal(cipherText);
System.out.println("Finish decryption:");
System.out.println(new String(newPlainText,"UTF8"));
}
}
4)数字签名:
/**
*DigitalSignature2Example.java
*Copyright 2005-2-16
*/
import java.security.Signature;
import java.security.KeyPairGenerator ;
import java.security.KeyPair;
import java.security.SignatureException;
/**
*数字签名,使用RSA私钥对对消息摘要签名,然后使用公鈅验证 测试
*/
public class DigitalSignature2Example{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java DigitalSignature2Example ");
System.exit(1);
}
byte[] plainText=args[0].getBytes("UTF8");
//形成RSA公钥对
System.out.println(" Start generating RSA key");
KeyPairGenerator keyGen=KeyPairGenerator .getInstance("RSA");
keyGen.initialize(1024);
KeyPair key=keyGen.generateKeyPair();
System.out.println("Finish generating RSA key");
//使用私鈅签名
Signature sig=Signature.getInstance("SHA1WithRSA");
sig.initSign(key.getPrivate());
sig.update(plainText);
byte[] signature=sig.sign();
System.out.println(sig.getProvider().getInfo());
System.out.println(" Signature:");
System.out.println(new String(signature,"UTF8"));
//使用公鈅验证
System.out.println(" Start signature verification");
sig.initVerify(key.getPublic());
sig.update(plainText);
try{
if(sig.verify(signature)){
System.out.println("Signature verified");
}else System.out.println("Signature failed");
}catch(SignatureException e){
System.out.println("Signature failed");
}
}
}
数字证书:它将一个身份标识连同公钥一起进行封装,并由称为认证中心或 CA 的第三方进行数字签名。
密钥库:java平台为你提供了密 钥库,用作密钥和证书的资源库。从物理上讲,密钥库是缺省名称为 .keystore 的文件(有一个选项使它成为加密文件)。密钥和证书可以拥有名称(称为别名),每个别名都由唯一的密码保护。密钥库本身也受密码保护;您可以选择让每个别 名密码与主密钥库密码匹配。
使用工具keytool ,我们来做一件自我认证的 事情吧(相信我的认证):
1、创建密钥库keytool -genkey -v -alias feiUserKey -keyalg RSA 默认在自己的home目录下(windows系统是c:documents and settings<你的用户名> 目录下的.keystore文件),创建我们用 RSA 算法生成别名为 feiUserKey 的自签名的证书,如果使用了-keystore mm 就在当前目录下创建一个密钥库mm文件来保存密钥和证书。
2、查看证书:keytool -list 列举了密钥库的所有的证书
也可以在dos下输入keytool -help查看帮助。
/**
*DigitalSignature2Example.java
*Copyright 2005-2-16
*/
import java.security.Signature;
import java.security.KeyPairGenerator ;
import java.security.KeyPair;
import java.security.SignatureException;
/**
*数字签名,使用RSA私钥对对消息摘要签名,然后使用公鈅验证 测试
*/
public class DigitalSignature2Example{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java DigitalSignature2Example ");
System.exit(1);
}
byte[] plainText=args[0].getBytes("UTF8");
//形成RSA公钥对
System.out.println(" Start generating RSA key");
KeyPairGenerator keyGen=KeyPairGenerator .getInstance("RSA");
keyGen.initialize(1024);
KeyPair key=keyGen.generateKeyPair();
System.out.println("Finish generating RSA key");
//使用私鈅签名
Signature sig=Signature.getInstance("SHA1WithRSA");
sig.initSign(key.getPrivate());
sig.update(plainText);
byte[] signature=sig.sign();
System.out.println(sig.getProvider().getInfo());
System.out.println(" Signature:");
System.out.println(new String(signature,"UTF8"));
//使用公鈅验证
System.out.println(" Start signature verification");
sig.initVerify(key.getPublic());
sig.update(plainText);
try{
if(sig.verify(signature)){
System.out.println("Signature verified");
}else System.out.println("Signature failed");
}catch(SignatureException e){
System.out.println("Signature failed");
}
}
}
5)数字证书。
数字证书:它将一个身份标识连同公钥一起进行封装,并由称为认证中心或 CA 的第三方进行数字签名。
密钥库:java平台为你提供了密 钥库,用作密钥和证书的资源库。从物理上讲,密钥库是缺省名称为 .keystore 的文件(有一个选项使它成为加密文件)。密钥和证书可以拥有名称(称为别名),每个别名都由唯一的密码保护。密钥库本身也受密码保护;您可以选择让每个别 名密码与主密钥库密码匹配。
使用工具keytool ,我们来做一件自我认证的 事情吧(相信我的认证):
1、创建密钥库keytool
相关推荐
在标签"mtk"、"mtk_software"和"mtk平台"方面,这些标签直接体现了软件与MediaTek芯片及其软件生态系统的紧密联系。"mtk_software"很可能指代那些针对MTK硬件进行优化的软件产品,它们在性能调优和兼容性方面进行了...
- 构建过滤图,将源过滤器与解码过滤器、渲染过滤器连接起来。 - 实现事件处理,例如播放、暂停、停止等。 - 控制播放,调用IMediaControl接口的方法启动、停止或暂停播放。 6. **错误处理**:由于DirectShow...
国内最好的数据库达梦DM8,曲奇网盘下载链接:https://quqi.com/s/1243222/wcOZdaWgUlHrwhOk
本代码是基于python pytorch环境安装的。 可参考博文进行安装环境运行代码-但需要先自行收集好图片放到对应文件夹下: https://blog.csdn.net/no_work/article/details/139246467 首先是代码的整体介绍 总共是3个py文件,十分的简便 本代码是不含数据集图片的,下载本代码后需要自行搜集图片放到对应的文件夹下即可 需要我们往每个文件夹下搜集来图片放到对应文件夹下,每个对应的文件夹里面也有一张提示图,提示图片放的位置 然后我们需要将搜集来的图片,直接放到对应的文件夹下,就可以对代码进行训练了。 运行01生成txt.py,是将数据集文件夹下的图片路径和对应的标签生成txt格式,划分了训练集和验证集 运行02CNN训练数据集.py,会自动读取txt文本内的内容进行训练,这里是适配了数据集的分类文件夹个数,即使增加了分类文件夹,也不需要修改代码即可训练 训练过程中会有训练进度条,可以查看大概训练的时长,每个epoch训练完后会显示准确率和损失值 训练结束后,会保存log日志,记录每个epoch的准确率和损失值 最后训练的模型会保
本代码是基于python pytorch环境安装的。 可参考博文进行安装环境运行代码-但需要先自行收集好图片放到对应文件夹下: https://blog.csdn.net/no_work/article/details/139246467 首先是代码的整体介绍 总共是3个py文件,十分的简便 本代码是不含数据集图片的,下载本代码后需要自行搜集图片放到对应的文件夹下即可 需要我们往每个文件夹下搜集来图片放到对应文件夹下,每个对应的文件夹里面也有一张提示图,提示图片放的位置 然后我们需要将搜集来的图片,直接放到对应的文件夹下,就可以对代码进行训练了。 运行01生成txt.py,是将数据集文件夹下的图片路径和对应的标签生成txt格式,划分了训练集和验证集 运行02CNN训练数据集.py,会自动读取txt文本内的内容进行训练,这里是适配了数据集的分类文件夹个数,即使增加了分类文件夹,也不需要修改代码即可训练 训练过程中会有训练进度条,可以查看大概训练的时长,每个epoch训练完后会显示准确率和损失值 训练结束后,会保存log日志,记录每个epoch的准确率和损失值 最后训练的模型会保
无人值守智能污水处理控制系统:西门子PLC与触摸屏的联动实践,稳定运营一年多,无人值守污水处理控制系统。 西门子200PLC和显控触摸屏编写的智能污水处理控制系统,有上位机编程软件,带图纸,带PLC程序,上位机画面,真实工程项目,已稳定运行一年多 ,核心关键词:无人值守;污水处理控制系统;西门子200PLC;显控触摸屏;智能控制;上位机编程软件;带图纸;带PLC程序;真实工程项目;稳定运行。,西门子智能无人污水处理系统控制方案
基于储能电站服务的冷热电多微网系统双层优化配置的MATLAB实现与仿真分析,MATLAB代码:基于储能电站服务的冷热电多微网系统双层优化配置 关键词:储能电站 共享储能电站 冷热电多微网 双层优化配置 参考文档:《基于储能电站服务的冷热电多微网系统双层优化配置》完全复现 仿真平台:MATLAB+CPLEx ,基于共享储能电站的冷热电多微网系统; 双层优化配置; MATLAB代码复现; CPLEx仿真平台; 完全复现; 储能电站服务。,基于储能电站共享的冷热电多微网系统双层优化配置研究——MATLAB+CPLEx仿真分析
西门子SMART模拟量滤波消抖子程序:滑动平均滤波法,连续采样N次有效处理,适用于高频干扰信号抑制,西门子SMART,模拟量滤波,消抖子程序 可做库,多次调用 滑动平均滤波法 方法:连续采样N次,把这N次存入一个队列,每次采集到的数据存入队尾,到达设定个数后把采样的数据从小到大排列(去掉一个最大最和最小值)剩余数据进行算术平均值,得到滤波结果 优点:对周期性干扰信号具有良好的抑制作用,特别适用于高频干扰信号 缺点:灵敏性低,对偶然出线的干扰抑制效果差 ,核心关键词:西门子SMART; 模拟量滤波; 消抖子程序; 滑动平均滤波法; 连续采样; 队列; 周期性干扰信号抑制; 高频干扰信号处理; 灵敏性低; 偶然干扰抑制。,西门子SMART模拟量处理:消抖子程序与滑动平均滤波库的实现
基于共享储能电站的工业用户日前经济调度优化:容量配置与充放电协同管理,MATLAB代码:基于共享储能电站的工业用户日前优化经济调度 关键词:共享储能 储能电站 容量优化配置 充放电优化 日前优化调度 参考文档:《基于共享储能电站的工业用户日前优化经济调度》完全复现 仿真平台:MATLAB+CPLEX 主要内容:代码主要做的是一个共享储能电站的优化调度问题,考虑在工业用户侧装设共享电站,从而满足不同工业用户的储能容量需求,同时,共享储能电站的容量是未知的,因此模型还涉及到容量优化配置的问题,即先配置再调度,所以内容十分丰富,由于模型中还出现了非线性项,考虑以Big-M法对模型进行线性化处理,通过协调各用户使用共享储能电站进行充电和放电的功率, 实现用户群日运行成本最优。 最后以江苏省 3 个工业用户进行算例仿真,求解效果与lunwen基本一致。 ,基于共享储能电站的工业用户容量优化与充放电调度策略研究
结合图像处理和深度学习的麦穗识别方法.pdf
f671569784024847c98c3dca416bba54
MATLAB中粒子群算法用于储能优化配置的最佳方案探索及图解分析,MATLAB代码:基于粒子群算法的储能优化配置 关键词:储能优化配置 粒子群 储能充放电优化 主要内容:建立了储能的成本模型,包含运行维护成本以及容量配置成本,然后以该成本函数最小为目标函数,经过粒子群算法求解出其最优运行计划,并通过其运行计划最终确定储能容量配置的大小,求解采用的是PSO算法(粒子群算法),求解效果极佳,具体可以看图 ,核心关键词:MATLAB代码; 储能优化配置; 粒子群算法; 成本模型; 运行维护成本; 容量配置成本; 运行计划; PSO算法(粒子群算法); 优化效果图。,基于PSO算法的储能充放电优化配置研究:成本最小化与运行计划优化
基于线性回归算法的时间序列预测MATLAB实现指导:推荐使用版本2018B及以上,基于线性回归(LR)算法的时间序列预测 LR时间序列 matlab代码 注:暂无Matlab版本要求 -- 推荐 2018B 版本及以上 ,核心关键词:基于线性回归(LR)算法; 时间序列预测; LR时间序列; Matlab代码; Matlab版本(推荐2018B及以上版本)。,基于Matlab的LR算法时间序列预测系统
永磁同步电机模型预测控制:从单矢量到双矢量预测,转矩控制及仿真研究,永磁同步电机(pmsm)模型预测控制(MPC)matla b simulink仿真模型,有PI矢量控制,直接预测控制(有限集模型预测控制)(这个其中包括做了单矢量和双矢量或者可以成为三矢量的有限集预测控制)和无差拿预测控制,模型预测控制可以是单环模型预测控制和双环模型预测控制,(基于龙伯格负载观测器)(foc控制)转矩 ,关键词:永磁同步电机(PMSM); 模型预测控制(MPC); MATLAB Simulink仿真模型; PI矢量控制; 有限集模型预测控制; 单矢量预测控制; 双矢量预测控制(或三矢量); 无差拍预测控制; 单环模型预测控制; 双环模型预测控制; 龙伯格负载观测器(LBO); FOC控制; 转矩,永磁同步电机MPC控制策略仿真研究:多控制方法与负载观测器应用
基于多目标粒子群算法的冷热电联供综合能源系统优化调度与运行管理策略,MATLAB代码:基于多目标粒子群算法冷热电联供综合能源系统运行优化 关键词:综合能源 冷热电三联供 粒子群算法 多目标优化 参考文档:《基于多目标算法的冷热电联供型综合能源系统运行优化》 仿真平台:MATLAB 平台采用粒子群实现求解 优势:代码注释详实,适合参考学习,非目前烂大街的版本,程序非常精品,请仔细辨识 主要内容:代码构建了含冷、热、电负荷的冷热电联供型综合能源系统优化调度模型,考虑了燃气轮机、电制冷机、锅炉以及风光机组等资源,并且考虑与上级电网的购电交易,综合考虑了用户购电购热冷量的成本、CCHP收益以及成本等各种因素,从而实现CCHP系统的经济运行,求解采用的是MOPSO算法(多目标粒子群算法),求解效果极佳,具体可以看图 ,核心关键词: 1. 综合能源系统 2. 冷热电三联供 3. 粒子群算法 4. 多目标优化 5. MATLAB平台 6. 优化调度模型 7. 燃气轮机 8. 电制冷机 9. 锅炉 10. 风光机组 用分号分隔的关键词结果为:综合能源系统; 冷热电三联供; 粒子群算法; 多目
**JavaShop 7.1.15:多用户B2B2C商城源码系统(Spring Boot + Webpack + Vue 架构,全面兼容PC+H5+APP)**,javashop7.1.15去授权,javaShop JAVA版多用户B2B2C商城源码(PC +H5+APP) 友情提示:此源码需要有java基础的开发人员 JAVA版多用户B2B2C商城源码(PC+H5+APP) 商城前台: http: buyer.javamall.com.cn 企业级基于Spring Boot构建,完全遵循RESTful规范, 齐全swagger文档,完整的单元测试 前后端完全分离,前端采用webpack+vue组件化模式 SpringCloud ReacrNative 微服务,前后端分离 包含pc + h5 +APP 赠送:安卓app+苹果app。 前后端分离架构,微服务架构 系统设计为“平台自营+供应商入驻”的电商运营模式, 系统支持佣金结算、团购、限时抢购、实时物流、后服务、 款原路 回等基础功能; 为电商运营商提供优质的系统和服务, 基于Java开发,支持插件式开发,通过AMQP实现消息总线
西门子PLC Smart200锁机与Smart700IE V3程序配套:分期付款、动态验证码、无限次加密程序实例探究,PLC 西门子smart200 锁机 配对应西门子smart700IE V3程序,分期期付款 动态验证码,无限次加密 程序例程 ,核心关键词:西门子smart200; PLC; 锁机; 配对应; 西门子smart700IE V3程序; 分期付款; 动态验证码; 无限次加密; 程序例程。,西门子PLC Smart系列:Smart200锁机与Smart700IE V3程序匹配指南
"基于滑动平均滤波算法的混合储能系统在5MW风电永磁直驱并网仿真中的应用",5MW风电永磁直驱-1200V直流并网仿真,带混合储能系统,其中采用滑动平均滤波算法(可改为自己想用的算法)对波动功率进行分解,然后交由储能系统进行平抑。 ,核心关键词:5MW风电永磁直驱; 1200V直流并网仿真; 混合储能系统; 功率波动分解; 滑动平均滤波算法(或其他算法); 储能系统平抑功率。,"5MW风电系统直流并网仿真:混合储能平抑功率波动,滑动平均滤波算法优化应用"
永磁同步电机(PMSM)无差拍预测控制:高效且易懂的MATLAB仿真模型及延时补偿策略,永磁同步电机(PMSM)无差拿预测控制MATLAB仿真模型。 程序编写简单易懂,具有一步延时补偿,无差拿和pwm调制结合,效果佳。 ,关键词:永磁同步电机(PMSM);无差拍预测控制;MATLAB仿真模型;一步延时补偿;pwm调制;效果佳。,永磁同步电机无差拍预测控制:MATLAB仿真模型,延时补偿与PWM调制优化