【问题标题】:How to hash and encode mpesa passcode in java如何在java中散列和编码mpesa密码
【发布时间】:2017-08-16 08:33:35
【问题描述】:

我正在尝试动态生成要与每个 api 请求一起发送到 mpesa apis 的密码。根据文档,我需要首先将提供的密码与时间戳和商家 ID 连接起来,然后执行 sha256 以获取哈希密码,然后我应该将其编码为 base 64 但是在 Java 中执行此操作会返回错误的编码字符串,而类似的过程和代码在 PHP 中工作,我哪里出错了?

import org.apache.commons.codec.binary.Base64;
import org.apache.cxf.headers.Header;
import org.apache.cxf.jaxb.JAXBDataBinding;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;



public class CheckoutHeaderBuilder {

    public static Header buildHeader(String merchantId, String passKey, String timestamp) throws JAXBException, NoSuchAlgorithmException, UnsupportedEncodingException {
    String hashedEncodedPass = Base64.encodeBase64String(MessageDigest.getInstance("SHA-256").digest((merchantId + passKey + timestamp).getBytes("utf-8")));

    List<Header> headers = new ArrayList<>();
    CheckOutHeader checkOutHeader = new CheckOutHeader();
    checkOutHeader.setTIMESTAMP(timestamp);
    checkOutHeader.setMERCHANTID(merchantId);
    checkOutHeader.setPASSWORD(hashedEncodedPass);
    return new Header(new QName("tns:ns", "CheckOutHeader"), checkOutHeader, new JAXBDataBinding(CheckOutHeader.class));

    }

}

【问题讨论】:

  • @zaph 注意,我已经相应地编辑了标题

标签: java sha mpesa


【解决方案1】:

您好Japheth Ongeri Inkalimeva,您不必使用 SHA256 进行加密。发送Lipa na M-Pesa Online Payment API 请求时,您可能不需要设置新密码。

我已修改您的代码以删除 SHA256 加密。

import org.apache.commons.codec.binary.Base64;
import org.apache.cxf.headers.Header;
import org.apache.cxf.jaxb.JAXBDataBinding;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;


public class CheckoutHeaderBuilder  {

    public static Header buildHeader(String merchantId, String passKey, String timestamp) throws JAXBException, NoSuchAlgorithmException, UnsupportedEncodingException {
    String hashedEncodedPass = Base64.encodeBase64String((merchantId + passKey + timestamp).getBytes("utf-8"));

    List<Header> headers = new ArrayList<>();
    CheckOutHeader checkOutHeader = new CheckOutHeader();
    checkOutHeader.setTIMESTAMP(timestamp);
    checkOutHeader.setMERCHANTID(merchantId);
    checkOutHeader.setPASSWORD(hashedEncodedPass);
    return new Header(new QName("tns:ns", "CheckOutHeader"), checkOutHeader, new JAXBDataBinding(CheckOutHeader.class));

    }

}

【讨论】:

  • 这行不通,它相当于以明文(仅使用 base64 编码)发送密码,而不使用高度不安全的散列。这就是文档特别需要 sha256 散列的原因。
  • @JaphethOngeri-inkalimeva 你不需要散列它。正如 API 文档指出的那样,您需要连接商家代码、密码和时间戳,然后将其编码为 base64。
【解决方案2】:

示例编码 SHA256

import java.nio.charset.StandardCharsets;
import com.google.common.hash.Hashing;

String password = “123456”;
Hashing.sha256().hashString(password, StandardCharsets.UTF_8).toString();

希望能帮到你

【讨论】:

    【解决方案3】:

    您可以这样对 Mpesa 的密码进行编码:

    import java.nio.charset.StandardCharsets;
    import java.util.Base64;
    
    public class MpesaUtils {
    
        public static String getMpesaEncodedPassword(String lipaNaMpesaShortCode,
                                  String password, String timeStamp) {
            StringBuilder sb = new StringBuilder();
            sb.append(lipaNaMpesaShortCode).append(password).append(timeStamp);
    
            byte[] bytes = sb.toString().getBytes(StandardCharsets.ISO_8859_1);
            return Base64.getEncoder().encodeToString(bytes);
        }
    }
    

    使用示例:

        String lnmShortCode = "your lipa na mpesa short code here";
        String password = "your password here";
        String timeStamp = getTimeStamp();
    
        String encodedPassword = MpesaUtils.getMpesaEncodedPassword(lnmShortCode, password, timeStamp);
    

    【讨论】:

      猜你喜欢
      • 2019-07-03
      • 1970-01-01
      • 2011-05-10
      • 2011-10-13
      • 2020-07-18
      • 2011-02-08
      • 2016-11-01
      • 2011-06-02
      • 2020-06-06
      相关资源
      最近更新 更多