Apache James数据库存储用户信息的密码加密问题及解决方案

本站所有内容来自互联网收集,仅供学习和交流,请勿用于商业用途。如有侵权、不妥之处,请第一时间联系我们删除!Q群:迪思分享

免费资源网 – https://freexyz.cn/

项目场景

Apache James邮件服务器使用数据库来存储用户信息的密码加密问题:

将James的用户改为数据库存储James密码是如何加密验证的

1.将James的用户改为数据库存储

1、修改存储方式

找到james-2.3.2appsjamesSAR-INFconfig.xml

Apache James数据库存储用户信息的密码加密问题及解决方案插图

找到<users-store>标签,注释掉原来文件存储的方式,改为数据库的方式

maildb:是后面配置的数据源名称

mail_users:是存储用户信息的表名

<users-store> <!– 注释掉原来文件存储的方式 –> <!– <repository name=”LocalUsers” class=”org.apache.james.userrepository.UsersFileRepository”> <destination URL=”file://var/users/”/> </repository> –> <!– 改为数据库的方式 –> <repository name=”LocalUsers” class=”org.apache.james.userrepository.JamesUsersJdbcRepository” destinationURL=”db://maildb/mail_users”> <sqlFile>file://conf/sqlResources.xml</sqlFile> </repository> </users-store>

 2.、配置数据库信息

找到<data-source>标签,根据具体数据库类型进行配置,下面已国产达梦数据库为例

Apache James数据库存储用户信息的密码加密问题及解决方案插图1

maildb:数据源名称 

<data-source name=”maildb” class=”org.apache.james.util.dbcp.JdbcDataSource”> <driver>dm.jdbc.driver.DmDriver</driver> <dburl>jdbc:dm://127.0.0.1:5236/test_mail</dburl> <user>test</user> <password>test123</password> <max>50</max> </data-source>

3、添加依赖包

因为我用的是达梦数据库,james里面没有这个数据库的依赖包,所以需要额外添加,如果是mysql、oracle常用的数据库就不需要再额外添加,因为james已经支持。

找到james-2.3.2lib,然后把需要的依赖包放进去

Apache James数据库存储用户信息的密码加密问题及解决方案插图2

4、创建用户表

正常情况下会自动创建,sql语句在james-2.3.2appsjamesconfsqlResources.xml

如果不会自动创建,那么自己把sql语句复制出来执行

CREATE TABLE “MAIL_USERS” ( “USERNAME” VARCHAR2(64) NOT NULL, “PWDHASH” VARCHAR2(50), “PWDALGORITHM” VARCHAR2(20), “USEFORWARDING” NUMBER(1,0), “FORWARDDESTINATION” VARCHAR2(255), “USEALIAS” NUMBER(1,0), “ALIAS” VARCHAR2(255), PRIMARY KEY(“USERNAME”) ); COMMENT ON TABLE “MAIL_USERS” IS James邮件用户; COMMENT ON COLUMN “MAIL_USERS”.”PWDALGORITHM” IS 加密方式,默认SHA; COMMENT ON COLUMN “MAIL_USERS”.”PWDHASH” IS 加密后的密码; COMMENT ON COLUMN “MAIL_USERS”.”USERNAME” IS 邮箱帐号;

 2.James密码是如何加密验证的

当你通过telnet添加新用户时,比如add user test 123456,你可以查看数据库中的记录,username字段是test,pwdhash是加密后的密码,pwdalgorithm字段是“SHA”,显然用的是SHA加密方式。

Apache James数据库存储用户信息的密码加密问题及解决方案插图3

让我们看下james源码是如何实现的,网上找到apache-james-2.3.2-src.zip源码文件,版本根据自己的来,然后用idea打开。

我们找到org.apache.james.userrepository.DefaultUser类

第一个方法verifyPassword()是用来做密码认证,传入的参数是明文密码,通过DigestUtil.digestString()方法,转换成密文密码,然后与数据库中密码作比较,返回比较结果。请注意这里的DigestUtil.digestString()方法,在后面还在提到。

第二个方法setPassword()是用于密码转换的,把明文转成密文,用的同样是DigestUtil.digestString()方法。

Apache James数据库存储用户信息的密码加密问题及解决方案插图4

        让我们再看下 org.apache.james.security.DigestUtil类,我们可以看到digestString加密的方法。

Apache James数据库存储用户信息的密码加密问题及解决方案插图5

如果需要在自己的项目里去添加或修改用户的信息,这时候密码处理的逻辑肯定需要跟james一致,这时候我们把这个加密的方法拷贝用就行了 。

创建个DigestUtil类,然后调用DigestUtil.digestString()来获得加密后的密码。

package com.mail; import javax.mail.MessagingException; import javax.mail.internet.MimeUtility; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class DigestUtil { public static String digestString(String pass, String algorithm ) throws NoSuchAlgorithmException { MessageDigest md; ByteArrayOutputStream bos; try { md = MessageDigest.getInstance(algorithm); byte[] digest = md.digest(pass.getBytes(“iso-8859-1”)); bos = new ByteArrayOutputStream(); OutputStream encodedStream = MimeUtility.encode(bos, “base64”); encodedStream.write(digest); return bos.toString(“iso-8859-1”); } catch (IOException ioe) { throw new RuntimeException(“Fatal error: ” + ioe); } catch (MessagingException me) { throw new RuntimeException(“Fatal error: ” + me); } } private DigestUtil() {} }

        加密支持的算法有MD5、SHA、SHA-256等 ,如果你想知道支持哪些算法,可以通过下面的代码列出所有支持的算法:

import java.security.Security; import java.security.Provider; import java.security.Provider.Service; public class ListAlgorithms { public static void main(String[] args) { for(Provider provider: Security.getProviders()) { for(Service service: provider.getServices()) { if (“MessageDigest”.equals(service.getType())) { System.out.println(service.getAlgorithm()); } } } } }

3.总结

集成java mail直接用明文帐号密码连接就行了,因为james会自己去加密验证,其他软件通过pop3配置,密码也是用明文就行了。

        如果觉得这种连接方式不安全有两种解决方案:

修改james源码,比较麻烦。密码在web端加密,传输到自己后台再解密,然后用解密后的密码连接james。 import javax.mail.*; import javax.mail.internet.*; import java.util.*; public class SendEmail { public static void main(String[] args) { String host = “smtp.example.com”; // SMTP服务器地址 String username = “your-username”; // 用户名 String password = “your-password”; // 密码 Properties props = new Properties(); props.put(“mail.smtp.host”, host); props.put(“mail.smtp.auth”, “true”); Session session = Session.getInstance(props, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { Message message = new MimeMessage(session); message.setFrom(new InternetAddress(“from@example.com”)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(“to@example.com”)); message.setSubject(“Email Subject”); message.setText(“Email Body”); Transport.send(message); System.out.println(“Email sent successfully”); } catch (MessagingException e) { throw new RuntimeException(“Error sending email”, e); } } }

Apache James数据库存储用户信息的密码加密问题及解决方案插图6


© 版权声明
THE END
★喜欢这篇文章吗?喜欢的话,麻烦动动手指支持一下!★
点赞7 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容