Apache James數(shù)據(jù)庫存儲用戶信息的密碼加密問題及解決方案
項目場景
Apache James郵件服務(wù)器使用數(shù)據(jù)庫來存儲用戶信息的密碼加密問題:
- 將James的用戶改為數(shù)據(jù)庫存儲
- James密碼是如何加密驗證的
1.將James的用戶改為數(shù)據(jù)庫存儲
1、修改存儲方式
找到j(luò)ames-2.3.2\apps\james\SAR-INF\config.xml

找到<users-store>標簽,注釋掉原來文件存儲的方式,改為數(shù)據(jù)庫的方式
maildb:是后面配置的數(shù)據(jù)源名稱
mail_users:是存儲用戶信息的表名
<users-store> <!-- 注釋掉原來文件存儲的方式 --> <!-- <repository name="LocalUsers" class="org.apache.james.userrepository.UsersFileRepository"> <destination URL="file://var/users/"/> </repository> --> <!-- 改為數(shù)據(jù)庫的方式 --> <repository name="LocalUsers" class="org.apache.james.userrepository.JamesUsersJdbcRepository" destinationURL="db://maildb/mail_users"> <sqlFile>file://conf/sqlResources.xml</sqlFile> </repository> </users-store>
2.、配置數(shù)據(jù)庫信息
找到<data-source>標簽,根據(jù)具體數(shù)據(jù)庫類型進行配置,下面已國產(chǎn)達夢數(shù)據(jù)庫為例

maildb:數(shù)據(jù)源名稱
<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、添加依賴包
因為我用的是達夢數(shù)據(jù)庫,james里面沒有這個數(shù)據(jù)庫的依賴包,所以需要額外添加,如果是mysql、oracle常用的數(shù)據(jù)庫就不需要再額外添加,因為james已經(jīng)支持。
找到j(luò)ames-2.3.2\lib,然后把需要的依賴包放進去

4、創(chuàng)建用戶表
正常情況下會自動創(chuàng)建,sql語句在james-2.3.2\apps\james\conf\sqlResources.xml
如果不會自動創(chuàng)建,那么自己把sql語句復制出來執(zhí)行
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,你可以查看數(shù)據(jù)庫中的記錄,username字段是test,pwdhash是加密后的密碼,pwdalgorithm字段是“SHA”,顯然用的是SHA加密方式。

讓我們看下james源碼是如何實現(xiàn)的,網(wǎng)上找到apache-james-2.3.2-src.zip源碼文件,版本根據(jù)自己的來,然后用idea打開。
我們找到org.apache.james.userrepository.DefaultUser類
第一個方法verifyPassword()是用來做密碼認證,傳入的參數(shù)是明文密碼,通過DigestUtil.digestString()方法,轉(zhuǎn)換成密文密碼,然后與數(shù)據(jù)庫中密碼作比較,返回比較結(jié)果。請注意這里的DigestUtil.digestString()方法,在后面還在提到。
第二個方法setPassword()是用于密碼轉(zhuǎn)換的,把明文轉(zhuǎn)成密文,用的同樣是DigestUtil.digestString()方法。

讓我們再看下 org.apache.james.security.DigestUtil類,我們可以看到digestString加密的方法。

如果需要在自己的項目里去添加或修改用戶的信息,這時候密碼處理的邏輯肯定需要跟james一致,這時候我們把這個加密的方法拷貝用就行了 。
創(chuàng)建個DigestUtil類,然后調(diào)用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.總結(jié)
集成java mail直接用明文帳號密碼連接就行了,因為james會自己去加密驗證,其他軟件通過pop3配置,密碼也是用明文就行了。
如果覺得這種連接方式不安全有兩種解決方案:
修改james源碼,比較麻煩。密碼在web端加密,傳輸?shù)阶约汉笈_再解密,然后用解密后的密碼連接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服務(wù)器地址
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);
}
}
}
到此這篇關(guān)于Apache James數(shù)據(jù)庫存儲用戶信息的密碼加密問題的文章就介紹到這了,更多相關(guān)Apache James密碼加密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VScode Remote SSH通過遠程編輯與調(diào)試代碼
這篇文章主要介紹了VScode Remote SSH通過遠程編輯與調(diào)試代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-05-05
Ubuntu18.04一次性升級Python所有庫的方法步驟
這篇文章主要介紹了Ubuntu18.04一次性升級Python所有庫的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-01-01
解讀Linux下ip命令展示的網(wǎng)絡(luò)連接信息
這篇文章主要給大家介紹了關(guān)于Linux下解讀ip命令展示的網(wǎng)絡(luò)連接信息的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起看看吧。2018-03-03
linux實現(xiàn)定時備份mysql數(shù)據(jù)庫的簡單方法
在本篇文章中我們給大家整理了一些關(guān)于linux實現(xiàn)定時備份mysql數(shù)據(jù)庫的簡單方法,有需要的朋友們可以學習下。2018-09-09

