Compare commits

...

4 Commits

Author SHA1 Message Date
Fin
b8ae5a0e3f 修复 AES-GCM 加解密不正确的问题 2025-10-31 15:45:18 +08:00
Fin
7180199607 修复 AES GCM 加密填充错误的问题 2025-10-30 16:28:15 +08:00
Fin
f995a7d15a 忽略 buildServer.json 文件 2025-10-30 14:29:28 +08:00
guanguans
762d0948eb docs: Add PHP for Bark link to README files
- Added a new link to the PHP for Bark repository in both English and Chinese README files.
- This provides users with additional resources for integrating Bark with PHP.
2025-10-30 12:03:51 +08:00
10 changed files with 111 additions and 89 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@ Pods/
.DS_Store
._.*
xcuserdata
buildServer.json

View File

@ -189,7 +189,11 @@ class CryptoSettingController: BaseViewController<CryptoSettingViewModel> {
.currentValueChanged
.compactMap { $0 }
.asDriver(onErrorDriveWith: .empty()),
modeChanged: self.modeFeild
.rx
.currentValueChanged
.compactMap { $0 }
.asDriver(onErrorDriveWith: .empty()),
copyScript: copyButton
.rx
.tap

View File

@ -14,6 +14,7 @@ import RxSwift
class CryptoSettingViewModel: ViewModel, ViewModelType {
struct Input {
let algorithmChanged: Driver<String>
let modeChanged: Driver<String>
let copyScript: Driver<CryptoSettingFields>
let done: Driver<CryptoSettingFields>
}
@ -55,6 +56,16 @@ class CryptoSettingViewModel: ViewModel, ViewModelType {
.compactMap { Algorithm(rawValue: $0) }
.map { $0.modes }
let paddingList = input
.modeChanged
.map { mode in
if mode == "GCM" {
return ["noPadding"]
} else {
return ["pkcs7"]
}
}
let keyLength =
Driver.merge([
Driver.just(dependencies.settingFieldRelay.value)
@ -95,43 +106,76 @@ class CryptoSettingViewModel: ViewModel, ViewModelType {
}
let copy = Driver.combineLatest(copyScript, dependencies.deviceKey, dependencies.serverAddress)
.compactMap { fields, deviceKey, serverAddress -> String? in
guard fields.mode != "GCM" else {
showSnackbar.accept("gcmNotSupported".localized)
return nil
}
let key = fields.key ?? ""
let iv = fields.iv ?? ""
return
"""
#!/usr/bin/env bash
# Documentation: \("encryptionUrl".localized)
set -e
if fields.mode == "GCM" {
return
"""
// Documentation: \("encryptionUrl".localized)
const crypto = require('crypto');
# bark key
deviceKey='\(deviceKey)'
# push payload
json='{"body": "test", "sound": "birdsong"}'
# \("keyComment".localized(with: Int(fields.algorithm.suffix(3))! / 8)) )
key='\(key)'
# \("ivComment".localized)
iv='\(iv)'
// bark key
const deviceKey = '\(deviceKey)';
// push payload
const json = JSON.stringify({ body: "test", sound: "birdsong" });
# \("opensslEncodingComment".localized)
key=$(printf $key | xxd -ps -c 200)
iv=$(printf $iv | xxd -ps -c 200)
# \("base64Notice".localized)
ciphertext=$(echo -n $json | openssl enc -aes-\(fields.algorithm.suffix(3))-\(fields.mode.lowercased()) -K $key \(iv.count > 0 ? "-iv $iv " : "")| base64)
// \("keyComment".localized(with: Int(fields.algorithm.suffix(3))! / 8))
const key = '\(key)';
// \("ivComment".localized)
const iv = '\(iv)';
# \("consoleComment".localized) "\((try? AESCryptoModel(cryptoFields: fields).encrypt(text: "{\"body\": \"test\", \"sound\": \"birdsong\"}")) ?? "")"
echo $ciphertext
# \("ciphertextComment".localized)
curl --data-urlencode "ciphertext=$ciphertext"\(iv.count == 0 ? "" : " --data-urlencode \"iv=\(iv)\"") \(serverAddress)/$deviceKey
"""
// AES-\(fields.algorithm.suffix(3))-GCM
const cipher = crypto.createCipheriv('aes-\(fields.algorithm.suffix(3))-gcm', Buffer.from(key, 'utf8'), Buffer.from(iv, 'utf8'));
const encrypted = Buffer.concat([
cipher.update(json, 'utf8'),
cipher.final()
]);
const tag = cipher.getAuthTag()
const combined = Buffer.concat([encrypted, tag])
let ciphertext = combined.toString('base64')
// \("consoleComment".localized) "\((try? AESCryptoModel(cryptoFields: fields).encrypt(text: "{\"body\":\"test\",\"sound\":\"birdsong\"}")) ?? "")"
console.log(ciphertext);
// \("ciphertextComment".localized)
const pushUrl = `\(serverAddress)/${deviceKey}?ciphertext=${encodeURIComponent(ciphertext)}&iv=${encodeURIComponent(iv)}`;
"""
} else {
return
"""
#!/usr/bin/env bash
# Documentation: \("encryptionUrl".localized)
set -e
# bark key
deviceKey='\(deviceKey)'
# push payload
json='{"body": "test", "sound": "birdsong"}'
# \("keyComment".localized(with: Int(fields.algorithm.suffix(3))! / 8)) )
key='\(key)'
# \("ivComment".localized)
iv='\(iv)'
# \("opensslEncodingComment".localized)
key=$(printf $key | xxd -ps -c 200)
iv=$(printf $iv | xxd -ps -c 200)
# \("base64Notice".localized)
ciphertext=$(echo -n $json | openssl enc -aes-\(fields.algorithm.suffix(3))-\(fields.mode.lowercased()) -K $key \(iv.count > 0 ? "-iv $iv " : "")| base64)
# \("consoleComment".localized) "\((try? AESCryptoModel(cryptoFields: fields).encrypt(text: "{\"body\": \"test\", \"sound\": \"birdsong\"}")) ?? "")"
echo $ciphertext
# \("ciphertextComment".localized)
curl --data-urlencode "ciphertext=$ciphertext"\(iv.count == 0 ? "" : " --data-urlencode \"iv=\(iv)\"") \(serverAddress)/$deviceKey
"""
}
}
return Output(
@ -142,7 +186,7 @@ class CryptoSettingViewModel: ViewModel, ViewModelType {
initialFields: dependencies.settingFieldRelay.value
)),
modeListChanged: modeList,
paddingListChanged: Driver.just(["pkcs7"]),
paddingListChanged: paddingList,
keyLengthChanged: keyLength,
showSnackbar: showSnackbar.asDriver(onErrorDriveWith: .empty()),
done: done.map { _ in () },

View File

@ -18,7 +18,7 @@ class HomeViewController: BaseViewController<HomeViewModel> {
let btn = BKButton()
btn.setImage(Icon.add, for: .normal)
btn.imageView?.tintColor = BKColor.grey.darken4
// btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
btn.accessibilityIdentifier = "AddServer".localized
return btn
}()
@ -27,7 +27,7 @@ class HomeViewController: BaseViewController<HomeViewModel> {
let btn = BKButton()
btn.setImage(UIImage(named: "baseline_filter_drama_black_24pt"), for: .normal)
btn.imageView?.tintColor = BKColor.grey.darken4
// btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
btn.accessibilityIdentifier = "serverList".localized
return btn
}()

View File

@ -21,13 +21,6 @@ enum Algorithm: String {
}
}
var paddings: [String] {
switch self {
case .aes128, .aes192, .aes256:
return ["pkcs7"]
}
}
var keyLength: Int {
switch self {
case .aes128:
@ -86,14 +79,24 @@ struct AESCryptoModel {
case "ECB":
mode = ECB()
case "GCM":
mode = GCM(iv: iv.bytes)
mode = GCM(iv: iv.bytes, mode: .combined)
default:
throw "Invalid Mode"
}
let padding: Padding
switch cryptoFields.padding {
case "noPadding":
padding = .noPadding
case "pkcs7":
padding = .pkcs7
default:
throw "Invalid Padding"
}
self.key = key
self.mode = mode
self.padding = Padding.pkcs7
self.padding = padding
self.aes = try AES(key: key.bytes, blockMode: self.mode, padding: self.padding)
}

View File

@ -14,18 +14,18 @@ PODS:
- IQKeyboardManagerSwift/Core
- IQKeyboardToolbarManager
- IQKeyboardNotification (1.0.6)
- IQKeyboardToolbar (1.1.2):
- IQKeyboardToolbar/Core (= 1.1.2)
- IQKeyboardToolbar/Core (1.1.2):
- IQKeyboardToolbar (1.1.3):
- IQKeyboardToolbar/Core (= 1.1.3)
- IQKeyboardToolbar/Core (1.1.3):
- IQKeyboardCore
- IQKeyboardToolbar/Placeholderable
- IQKeyboardToolbar/Placeholderable (1.1.2)
- IQKeyboardToolbar/Placeholderable (1.1.3)
- IQKeyboardToolbarManager (1.1.4):
- IQKeyboardToolbar
- IQTextInputViewNotification
- IQTextInputViewNotification (1.0.9):
- IQKeyboardCore
- Kingfisher (8.6.0)
- Kingfisher (8.6.1)
- Material (3.1.8):
- Material/Core (= 3.1.8)
- Material/Core (3.1.8):
@ -146,10 +146,10 @@ SPEC CHECKSUMS:
IQKeyboardCore: 8652977ec919cf5351aa2977fedd1a6546476fbc
IQKeyboardManagerSwift: 835fc9c6e4732398113406d84900ad2e8f141218
IQKeyboardNotification: eb4910401f5a0e68f97e71c62f8a0c5b7e9d535c
IQKeyboardToolbar: a8aab764a27d55892b951e58ebfffdde14a01ce8
IQKeyboardToolbar: 9fe900f8e7def414be4025af0ca098df764d4fe3
IQKeyboardToolbarManager: c8a575e8b5fffe5873d0e75312244498a0759473
IQTextInputViewNotification: 3b9fb27a16e7ee8958cc9092cfb07a1a9e1fd559
Kingfisher: 64278f126a815d0e2d391cdf71311b85882c4de0
Kingfisher: 7ac7a7288653787a54206b11a3c74f49ab650f1f
Material: a2a3f400a3b549d53ef89e56c58c4535b29db387
MercariQRScanner: cd024685242f78fe40879cca9734bb7bb2fceb93
MJRefresh: ff9e531227924c84ce459338414550a05d2aea78

View File

@ -99,3 +99,4 @@ Critical alerts will ignore silent and do not disturb modes, always playing the
- [bark-java-sdk](https://github.com/MoshiCoCo/bark-java-sdk)
- [Python for Bark](https://github.com/funny-cat-happy/barknotificator)
- [uTools for Bark](https://u.tools/plugins/detail/PushOne/)
- [PHP for Bark](https://github.com/guanguans/notify/tree/main/src/Bark/)

View File

@ -99,3 +99,4 @@ https://api.day.app/yourkey/时效性通知?level=critical
- [bark-java-sdk](https://github.com/MoshiCoCo/bark-java-sdk)
- [Python for Bark](https://github.com/funny-cat-happy/barknotificator)
- [uTools for Bark](https://u.tools/plugins/detail/PushOne/)
- [PHP for Bark](https://github.com/guanguans/notify/tree/main/src/Bark/)

View File

@ -7,12 +7,11 @@
//
import DropDown
import UIKit
import RxCocoa
import RxSwift
import UIKit
class DropBoxView: UIView {
let valueLabel: UILabel = {
let label = UILabel()
label.font = UIFont.preferredFont(ofSize: 14)
@ -35,8 +34,7 @@ class DropBoxView: UIView {
self.borderColor = BKColor.blue.darken5
self.shadowColor = BKColor.blue.darken5
self.layer.shadowOpacity = 0.3
}
else {
} else {
self.borderColor = BKColor.grey.lighten2
self.shadowColor = BKColor.grey.lighten2
self.layer.shadowOpacity = 0
@ -54,11 +52,11 @@ class DropBoxView: UIView {
var currentValue: String? {
didSet {
self.valueLabel.text = currentValue
self.currentValueChanged?(self.currentValue)
self.currentValueSubject.onNext(self.currentValue)
}
}
var currentValueChanged: ((String?) -> Void)?
fileprivate let currentValueSubject = PublishSubject<String?>()
init(values: [String]) {
self.values = values
@ -120,19 +118,8 @@ class DropBoxView: UIView {
}
extension Reactive where Base: DropBoxView {
var currentValueChanged: ControlEvent<String?> {
let source = Observable<String?>.create { [weak control = self.base] observer -> Disposable in
MainScheduler.ensureExecutingOnScheduler()
guard let control = control else {
observer.onCompleted()
return Disposables.create()
}
control.currentValueChanged = { value in
observer.onNext(value)
}
return Disposables.create()
}
let source = base.currentValueSubject.asObservable()
return ControlEvent(events: source)
}
}

View File

@ -1,19 +0,0 @@
{
"name": "xcode build server",
"version": "0.2",
"bspVersion": "2.0",
"languages": [
"c",
"cpp",
"objective-c",
"objective-cpp",
"swift"
],
"argv": [
"/opt/homebrew/bin/xcode-build-server"
],
"workspace": "/Users/huangfeng/Documents/Bark/Bark.xcworkspace",
"build_root": "/Users/huangfeng/Library/Developer/Xcode/DerivedData/Bark-cyorhgfjlviqbhgulankypxaozte",
"scheme": "Bark",
"kind": "xcode"
}