项目中需要与delphi交换。为了增强安全性这两天学习了下几种算法今晚把这两天的心得及代码贴上来交流下:
我们的想法是这样的:
delphi生成密匙文件。java使用密匙文件加密或解密。delphi也使用同一个密匙文件加密或解密。我做了两种加密方式的实现rsa跟des。我做完后发现两个方式使用java生成的密匙文件文件加密解密都是没问题的,但使用delphi生成的密匙文件就不能加密或解密。下面我把我的代码贴上来请指点下。
一。加密接口
import java.io.IOException;
public interface CodeBean {
/**
* 编码
* @return
*/
public byte[] encode(byte [] cipherText)throws Exception;
/**
* 解码
* @return
*/
public byte[] decode(byte [] cipherText)throws Exception;
}
二。Rsa加密实现
public class RsaEncoder implements InitializingBean, CodeBean {
private final String KEY_ENCODE = "ENCODE";// 编码
private final String KEY_DECODE = "DECODE";// 解码
private String chartSet = "UTF-8";
private String publickey;// ENCODE/DECODE
private String privatekey;// ENCODE/DECODE
private String publicKeyPath = null;
private String privatekeypath = null;
public void afterPropertiesSet() throws Exception {
if (!StringUtils.hasText(this.getPrivatekey()) && !StringUtils.hasText(this.getPublickey()))
throw new BeanInitializationException("请设置publickey或privatekey值");
if (StringUtils.hasText(this.getPublickey()))
Assert.notNull(publicKeyPath);
if (StringUtils.hasText(this.getPrivatekey()))
Assert.notNull(privatekeypath);
}
/**
* 解码
*
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws InvalidKeySpecException
*/
public byte[] decode(byte [] cipherText) throws Exception {
Cipher cipher = null;
if (KEY_DECODE.equals(this.getPublickey())) {
PublicKey pubKey = (PublicKey)loadKey(this.getPublicKeyPath(),1);
cipher = Cipher.getInstance("RSA",new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, pubKey);
} else {
PrivateKey privKey = (PrivateKey)loadKey(this.getPrivatekeypath(),0);
cipher = Cipher.getInstance("RSA",new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, privKey);
}
byte[] newPlainText = cipher.doFinal(cipherText);
return newPlainText;
}
/**
* 加密
* @param cipherText
* @return
* @throws IOException
*/
public byte[] encode(byte [] cipherText) throws Exception {
Cipher cipher = null;
KeyFactory keyFactory = KeyFactory.getInstance("RSA",new BouncyCastleProvider());
if (KEY_ENCODE.equals(this.getPublickey())) {
PublicKey pubKey = (PublicKey)loadKey(this.getPublicKeyPath(),1);
//cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher = Cipher.getInstance("RSA",new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
} else {
PrivateKey privKey = (PrivateKey)loadKey(this.getPrivatekeypath(),0);
//cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher = Cipher.getInstance("RSA",new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, privKey);
}
byte[] newPlainText = cipher.doFinal(cipherText);
return newPlainText;
}
/**
* @param filename
* @param type:
* 1-public 0-private
* @return
* @throws ConfigurationException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
public Key loadKey(String filename, int type) throws Exception {
System.out.println("filename:" + filename);
PropertiesConfiguration config = new PropertiesConfiguration(filename);
KeyFactory keyFactory = KeyFactory.getInstance("RSA", new BouncyCastleProvider());
File file = new File(filename);
if (filename == null || filename.equals("")) {
throw new NullPointerException("无效的文件路径");
}
long len = file.length();
byte[] bytes = new byte[(int) len];
BufferedInputStream bufferedInputStream = new BufferedInputStream( new FileInputStream(file));
int r = bufferedInputStream.read(bytes);
if (r != len)
throw new IOException("读取文件不正确");
bufferedInputStream.close();
if (type == 0) {
// privateKey
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(bytes);
PrivateKey privateKey = keyFactory.generatePrivate(priPKCS8);
return privateKey;
} else {
// publicKey
X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bytes);
PublicKey publicKey = keyFactory.generatePublic(bobPubKeySpec);
return publicKey;
}
}
public String getPrivatekeypath() {
return privatekeypath;
}
public void setPrivatekeypath(String privatekeypath) {
this.privatekeypath = privatekeypath;
}
public String getPublicKeyPath() {
return publicKeyPath;
}
public void setPublicKeyPath(String publicKeyPath) {
this.publicKeyPath = publicKeyPath;
}
public String getPrivatekey() {
return privatekey;
}
public void setPrivatekey(String privatekey) {
this.privatekey = privatekey.toUpperCase();
}
public String getPublickey() {
return publickey;
}
public void setPublickey(String publickey) {
this.publickey = publickey.toUpperCase();
}
public String getChartSet() {
return chartSet;
}
public void setChartSet(String chartSet) {
this.chartSet = chartSet;
}
public String getKEY_ENCODE() {
return KEY_ENCODE;
}
public String getKEY_DECODE() {
return KEY_DECODE;
}
}
Rsa加密解密的测试
public static void main(String[]arg){
byte[] byt = null;
try {
String encryptText = "ouxueying";
System.out.println("第一种方式..........................");
RsaEncoder rsaEncoder1 = new RsaEncoder();
rsaEncoder1.setChartSet("utf-8");
rsaEncoder1.setPrivatekey("ENCODE");//DECODE
rsaEncoder1.setPrivatekeypath("F:\\PrivateKey.key");
rsaEncoder1.setPublickey("DECODE");//ENCODE
rsaEncoder1.setPublicKeyPath("F:\\PublicKey.key");
System.out.println("加密:..........." );
byte [] byt1 = rsaEncoder1.encode(encryptText.getBytes());
//System.out.println("加密结果:" + toHexString(byt));
System.out.println("解密:..........." );
byte[] b1 = rsaEncoder1.decode(byt1);
System.out.println("解密结果: " + new String(b1));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
三。des加密解密的实现
public class DesEncoder implements CodeBean {
Cipher ecipher;
Cipher dcipher;
//密匙路径
private String keyPath = null;
public static void main(String[] arg) {
String str = "123";
try {
DesEncoder des = new DesEncoder();
des.setKeyPath("F:\\desKey.key");
//SecretKey se = des.generateKey();
//des.saveKey(des.getKeyPath(),se);
//System.out.println("MD5 KEY完成");
des.init(des.loadKey(des.getKeyPath()));
byte[] utf8 = str.getBytes();
byte[] enc = des.encode(utf8);
String s = Converts.bytesToHexString(enc);
System.out.println("加密结果:" + s);
//byte[] enc = "02BB6C".getBytes();
byte[] utf = des.decode(enc);
System.out.println("结果:" + new String(utf,"UTF-8"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 初始化加密器
* @param key
*/
public void init(SecretKey key) {
try {
ecipher = Cipher.getInstance("DES");
dcipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
} catch (javax.crypto.NoSuchPaddingException e) {
} catch (java.security.NoSuchAlgorithmException e) {
} catch (java.security.InvalidKeyException e) {
}
}
/**
* 生成KEY
* @return
* @throws Exception
*/
public SecretKey generateKey() throws Exception {
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
this.saveKey(this.getKeyPath(), key);
return key;
}
/**
* 解码
*/
public byte[] decode(byte[] dec) throws Exception {
byte[] utf8 = dcipher.doFinal(dec);
return utf8;
}
/**
* 编码
*/
public byte[] encode(byte[] utf8) throws Exception {
byte[] enc = ecipher.doFinal(utf8);
return enc;
}
/**
* 从密匙文件生成KEY
* @param filename
* @return
* @throws Exception
*/
public SecretKey loadKey(String filename) throws Exception {
System.out.println("filename:" + filename);
//实例化文件对象
File file = new File(filename);
if (filename == null || filename.equals("")) {
throw new NullPointerException("无效的文件路径");
}
long len = file.length();
byte[] bytes = new byte[(int) len];
BufferedInputStream bufferedInputStream = new BufferedInputStream( new FileInputStream(file));
//读取密匙文件
int r = bufferedInputStream.read(bytes);
if (r != len)
throw new IOException("读取文件不正确");
bufferedInputStream.close();
byte rawKeyData[] = bytes;
// 从原始密匙数据创建一个DESKeySpec对象
DESKeySpec dks = new DESKeySpec(rawKeyData);
// 创建一个密匙工厂,然后用它把DESKeySpec对象转换成
// 一个SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(dks);
return key;
}
/**
* 将密匙存到密匙文件中
* @param filename
* @param key
* @throws Exception
*/
public void saveKey(String filename, Key key) throws Exception {
System.out.println("保存filename:" + filename);
File file = new File(filename);
BufferedOutputStream pubout = new BufferedOutputStream(new FileOutputStream(filename));
byte[] keyt = key.getEncoded();
java.security.MessageDigest md = java.security.MessageDigest.getInstance( "MD5" );
md.update( keyt );
byte tmp[] = md.digest();
// System.out.println(Converts.);
pubout.write(tmp);
pubout.close();
}
public String getKeyPath() {
return keyPath;
}
public void setKeyPath(String keyPath) {
this.keyPath = keyPath;
}
}
四.在使用delphi密匙时rsa des都会报错:
java.security.spec.InvalidKeySpecException: java.lang.IllegalArgumentException: unknown object in factory
at org.bouncycastle.jce.provider.JDKKeyFactory$RSA.engineGeneratePublic(Unknown Source)
at java.security.KeyFactory.generatePublic(KeyFactory.java:278)
at com.hitech.cpp.components.encoding.RsaEncoder.loadKey(Unknown Source)
at com.hitech.cpp.components.encoding.RsaEncoder.decode(Unknown Source)
at com.hitech.cpp.components.encoding.RsaEncoderTest.main(Unknown Source)
分享到:
相关推荐
基于springboot大学生就业信息管理系统源码数据库文档.zip
基于java的驾校收支管理可视化平台的开题报告
时间序列 原木 间隔5秒钟 20241120
毕业设计&课设_基于 Vue 的电影在线预订与管理系统:后台 Java(SSM)代码,为毕业设计项目.zip
基于springboot课件通中小学教学课件共享平台源码数据库文档.zip
基于java的网上购物商城的开题报告
Delphi人脸检测与识别Demo1fdef-main.zip
基于java的咖啡在线销售系统的开题报告
基于java的自助医疗服务系统的开题报告.docx
内容概要:本文档全面介绍了Visual Basic(VB)编程语言的基础知识和高级应用。首先概述了VB的基本特性和开发环境,随后详细讲述了VB的数据类型、变量、运算符、控制结构、数组、过程与函数、变量作用域等内容。接着介绍了窗体设计、控件使用、菜单与工具栏的设计,文件操作、数据库访问等关键知识点。最后讨论了VB的学习方法、发展历史及其在桌面应用、Web应用、数据库应用、游戏开发和自动化脚本编写等领域的广泛应用前景。 适合人群:初学者和中级程序员,尤其是希望快速掌握Windows桌面应用开发的人群。 使用场景及目标:①掌握VB的基础语法和开发环境;②学会使用VB创建复杂的用户界面和功能完整的应用程序;③理解数据库操作、文件管理和网络编程等高级主题。 其他说明:Visual Basic是一种简单易学且功能强大的编程语言,尤其适合用于开发Windows桌面应用。文中不仅覆盖了基础知识,还包括了大量的实用案例和技术细节,帮助读者快速提升编程技能。
基于java的疫情期间高校防控系统开题报告.docx
基于springboot+vue社区老年人帮扶系统源码数据库文档.zip
基于java的超市商品管理系统的开题报告.docx
基于SpringBoot房屋买卖平台源码数据库文档.zip
xdu限通院23微处理器系统与应用大作业(两只老虎),适应于汇编语言keil软件,
<项目介绍> - 新闻类网站系统,基于SSM(Spring、Spring MVC、MyBatis)+MySQL开发,高分成品毕业设计,附带往届论文 - 不懂运行,下载完可以私聊问,可远程教学 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
基于java的学生网上请假系统的开题报告.docx
社会经济繁荣发展的今天,电子商务得到了飞速发展,网上交易越来越彰显出其独特的优越性,在人们的日常生活中,出现了各种类型的交易网站。其中一个就是车辆易主交易网站,它是一个服务于用户买卖二手车辆的交易网站,为用户提供了平等互利、方便快捷的网上交易平台,通过这一类型的网站,用户可自由出售和购买车辆。 本课题主要根据车辆本身的特性,充分发挥互联网的特点与优势,构建一个以二手车辆为商品、基于互联网平台的车辆易主业务交易管理系统,并根据车辆易主业务交易管理系统的应用需求,进行需求分析,进而对网站系统作规划设计。采用IDEA为运行平台,以SSH为框架,运用HTML语言、JSP技术、MySql数据库、JSP与后台数据库链接等关键技术建设二手车网上交易系统,构建车辆易主交易系统的会员注册与登录,网站首页展示、用户发布商品车辆,用户求购商品车辆,分页浏览、购物系统、用户后台管理、管理员用户后台管理等功能,并使这些功能得以实现并更好为用户服务。网站整体构建完成且测试成功后,用户可以进入网站进行注册、登录,登录后,用户可以在网站上发布自己的闲置车辆或者寻找想要购买的车辆,还可以收藏车辆,管理发布和收藏的车辆,
SQLite3的向量扩展库,windows dll,版本0.1.5
基于C++实现(控制台)商品库存管理系统